1edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Copyright (c) 2004 Python Software Foundation. 2edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# All rights reserved. 3edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Written by Eric Price <eprice at tjhsst.edu> 5edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# and Facundo Batista <facundo at taniquetil.com.ar> 6edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# and Raymond Hettinger <python at rcn.com> 7edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# and Aahz <aahz at pobox.com> 8edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# and Tim Peters 9edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 10edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# This module is currently Py2.3 compatible and should be kept that way 11edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# unless a major compelling advantage arises. IOW, 2.3 compatibility is 12edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# strongly preferred, but not guaranteed. 13edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 14edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Also, this module should be kept in sync with the latest updates of 15edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# the IBM specification as it evolves. Those updates will be treated 16edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# as bug fixes (deviation from the spec is a compatibility, usability 17edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# bug) and will be backported. At this point the spec is stabilizing 18edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# and the updates are becoming fewer, smaller, and less significant. 19edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 20edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""" 21edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepThis is a Py2.3 implementation of decimal floating point arithmetic based on 22edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepthe General Decimal Arithmetic Specification: 23edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 24edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep http://speleotrove.com/decimal/decarith.html 25edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 26edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepand IEEE standard 854-1987: 27edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 28edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html 29edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 30edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal floating point has finite precision with arbitrarily large bounds. 31edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 32edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepThe purpose of this module is to support arithmetic using familiar 33edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep"schoolhouse" rules and to avoid some of the tricky representation 34edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepissues associated with binary floating point. The package is especially 35edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepuseful for financial applications or for contexts where users have 36edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepexpectations that are at odds with binary floating point (for instance, 37edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepin binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead 38edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepof the expected Decimal('0.00') returned by decimal floating point). 39edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 40edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepHere are some examples of using the decimal module: 41edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 42edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> from decimal import * 43edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> setcontext(ExtendedContext) 44edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> Decimal(0) 45edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('0') 46edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> Decimal('1') 47edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('1') 48edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> Decimal('-.0123') 49edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('-0.0123') 50edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> Decimal(123456) 51edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('123456') 52edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> Decimal('123.45e12345678901234567890') 53edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('1.2345E+12345678901234567892') 54edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> Decimal('1.33') + Decimal('1.27') 55edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('2.60') 56edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> Decimal('12.34') + Decimal('3.87') - Decimal('18.41') 57edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('-2.20') 58edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> dig = Decimal(1) 59edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print dig / Decimal(3) 60edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep0.333333333 61edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> getcontext().prec = 18 62edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print dig / Decimal(3) 63edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep0.333333333333333333 64edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print dig.sqrt() 65edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep1 66edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print Decimal(3).sqrt() 67edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep1.73205080756887729 68edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print Decimal(3) ** 123 69edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep4.85192780976896427E+58 70edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> inf = Decimal(1) / Decimal(0) 71edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print inf 72edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepInfinity 73edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> neginf = Decimal(-1) / Decimal(0) 74edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print neginf 75edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep-Infinity 76edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print neginf + inf 77edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepNaN 78edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print neginf * inf 79edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep-Infinity 80edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print dig / 0 81edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepInfinity 82edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> getcontext().traps[DivisionByZero] = 1 83edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print dig / 0 84edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTraceback (most recent call last): 85edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ... 86edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ... 87edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ... 88edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDivisionByZero: x / 0 89edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> c = Context() 90edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> c.traps[InvalidOperation] = 0 91edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print c.flags[InvalidOperation] 92edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep0 93edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> c.divide(Decimal(0), Decimal(0)) 94edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('NaN') 95edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> c.traps[InvalidOperation] = 1 96edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print c.flags[InvalidOperation] 97edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep1 98edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> c.flags[InvalidOperation] = 0 99edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print c.flags[InvalidOperation] 100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep0 101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print c.divide(Decimal(0), Decimal(0)) 102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTraceback (most recent call last): 103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ... 104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ... 105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ... 106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepInvalidOperation: 0 / 0 107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print c.flags[InvalidOperation] 108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep1 109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> c.flags[InvalidOperation] = 0 110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> c.traps[InvalidOperation] = 0 111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print c.divide(Decimal(0), Decimal(0)) 112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepNaN 113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print c.flags[InvalidOperation] 114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep1 115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> 116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""" 117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep__all__ = [ 119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Two major classes 120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'Decimal', 'Context', 121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Contexts 123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'DefaultContext', 'BasicContext', 'ExtendedContext', 124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Exceptions 126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero', 127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow', 128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Constants for use in setting up contexts 130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING', 131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 'ROUND_05UP', 132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Functions for manipulating contexts 134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'setcontext', 'getcontext', 'localcontext' 135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep] 136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep__version__ = '1.70' # Highest version of the spec this complies with 138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport copy as _copy 140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport math as _math 141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport numbers as _numbers 142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoeptry: 144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep from collections import namedtuple as _namedtuple 145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent') 146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepexcept ImportError: 147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep DecimalTuple = lambda *args: args 148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Rounding 150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_DOWN = 'ROUND_DOWN' 151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_HALF_UP = 'ROUND_HALF_UP' 152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_HALF_EVEN = 'ROUND_HALF_EVEN' 153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_CEILING = 'ROUND_CEILING' 154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_FLOOR = 'ROUND_FLOOR' 155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_UP = 'ROUND_UP' 156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_HALF_DOWN = 'ROUND_HALF_DOWN' 157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_05UP = 'ROUND_05UP' 158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Errors 160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass DecimalException(ArithmeticError): 162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Base exception class. 163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Used exceptions derive from this. 165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If an exception derives from another exception besides this (such as 166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Underflow (Inexact, Rounded, Subnormal) that indicates that it is only 167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep called if the others are present. This isn't actually used for 168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep anything, though. 169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep handle -- Called when context._raise_error is called and the 171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep trap_enabler is not set. First argument is self, second is the 172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context. More arguments can be given, those being after 173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the explanation in _raise_error (For example, 174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(NewError, '(-x)!', self._sign) would 175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep call NewError().handle(context, self._sign).) 176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep To define a new exception, it should be sufficient to have it derive 178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep from DecimalException. 179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def handle(self, context, *args): 181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep pass 182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Clamped(DecimalException): 185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Exponent of a 0 changed to fit bounds. 186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This occurs and signals clamped if the exponent of a result has been 188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep altered in order to fit the constraints of a specific concrete 189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep representation. This may occur when the exponent of a zero result would 190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep be outside the bounds of a representation, or when a large normal 191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep number would have an encoded exponent that cannot be represented. In 192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep this latter case, the exponent is reduced to fit and the corresponding 193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep number of zero digits are appended to the coefficient ("fold-down"). 194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass InvalidOperation(DecimalException): 197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """An invalid operation was performed. 198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Various bad things cause this: 200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Something creates a signaling NaN 202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -INF + INF 203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 0 * (+-)INF 204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (+-)INF / (+-)INF 205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep x % 0 206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (+-)INF % x 207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep x._rescale( non-integer ) 208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sqrt(-x) , x > 0 209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 0 ** 0 210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep x ** (non-integer) 211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep x ** (+-)INF 212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep An operand is invalid 213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The result of the operation after these is a quiet positive NaN, 215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep except when the cause is a signaling NaN, in which case the result is 216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep also a quiet NaN, but with the original sign, and an optional 217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep diagnostic information. 218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def handle(self, context, *args): 220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if args: 221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(args[0]._sign, args[0]._int, 'n', True) 222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans._fix_nan(context) 223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NaN 224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass ConversionSyntax(InvalidOperation): 226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Trying to convert badly formed string. 227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This occurs and signals invalid-operation if an string is being 229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep converted to a number and it does not conform to the numeric string 230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep syntax. The result is [0,qNaN]. 231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def handle(self, context, *args): 233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NaN 234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass DivisionByZero(DecimalException, ZeroDivisionError): 236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Division by 0. 237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This occurs and signals division-by-zero if division of a finite number 239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep by zero was attempted (during a divide-integer or divide operation, or a 240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep power operation with negative right-hand operand), and the dividend was 241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep not zero. 242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The result of the operation is [sign,inf], where sign is the exclusive 244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep or of the signs of the operands for divide, or is 1 for an odd power of 245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -0, for power. 246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def handle(self, context, sign, *args): 249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _SignedInfinity[sign] 250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass DivisionImpossible(InvalidOperation): 252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Cannot perform the division adequately. 253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This occurs and signals invalid-operation if the integer result of a 255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep divide-integer or remainder operation had too many digits (would be 256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep longer than precision). The result is [0,qNaN]. 257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def handle(self, context, *args): 260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NaN 261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass DivisionUndefined(InvalidOperation, ZeroDivisionError): 263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Undefined result of division. 264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This occurs and signals invalid-operation if division by zero was 266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep attempted (during a divide-integer, divide, or remainder operation), and 267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the dividend is also zero. The result is [0,qNaN]. 268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def handle(self, context, *args): 271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NaN 272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Inexact(DecimalException): 274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Had to round, losing information. 275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This occurs and signals inexact whenever the result of an operation is 277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep not exact (that is, it needed to be rounded and any discarded digits 278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep were non-zero), or if an overflow or underflow condition occurs. The 279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result in all cases is unchanged. 280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The inexact signal may be tested (or trapped) to determine if a given 282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep operation (or sequence of operations) was inexact. 283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass InvalidContext(InvalidOperation): 286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Invalid context. Unknown rounding, for example. 287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This occurs and signals invalid-operation if an invalid context was 289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep detected during an operation. This can occur if contexts are not checked 290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep on creation and either the precision exceeds the capability of the 291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep underlying concrete representation or an unknown or unsupported rounding 292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep was specified. These aspects of the context need only be checked when 293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the values are required to be used. The result is [0,qNaN]. 294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def handle(self, context, *args): 297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NaN 298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Rounded(DecimalException): 300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Number got rounded (not necessarily changed during rounding). 301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This occurs and signals rounded whenever the result of an operation is 303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rounded (that is, some zero or non-zero digits were discarded from the 304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coefficient), or if an overflow or underflow condition occurs. The 305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result in all cases is unchanged. 306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The rounded signal may be tested (or trapped) to determine if a given 308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep operation (or sequence of operations) caused a loss of precision. 309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Subnormal(DecimalException): 312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Exponent < Emin before rounding. 313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This occurs and signals subnormal whenever the result of a conversion or 315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep operation is subnormal (that is, its adjusted exponent is less than 316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Emin, before any rounding). The result in all cases is unchanged. 317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The subnormal signal may be tested (or trapped) to determine if a given 319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep or operation (or sequence of operations) yielded a subnormal result. 320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Overflow(Inexact, Rounded): 323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Numerical overflow. 324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This occurs and signals overflow if the adjusted exponent of a result 326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (from a conversion or from an operation that is not an attempt to divide 327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep by zero), after rounding, would be greater than the largest value that 328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep can be handled by the implementation (the value Emax). 329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The result depends on the rounding mode: 331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep For round-half-up and round-half-even (and for round-half-down and 333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep round-up, if implemented), the result of the operation is [sign,inf], 334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep where sign is the sign of the intermediate result. For round-down, the 335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result is the largest finite number that can be represented in the 336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep current precision, with the sign of the intermediate result. For 337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep round-ceiling, the result is the same as for round-down if the sign of 338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the intermediate result is 1, or is [0,inf] otherwise. For round-floor, 339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the result is the same as for round-down if the sign of the intermediate 340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded 341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep will also be raised. 342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def handle(self, context, sign, *args): 345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN, 346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ROUND_HALF_DOWN, ROUND_UP): 347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _SignedInfinity[sign] 348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sign == 0: 349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context.rounding == ROUND_CEILING: 350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _SignedInfinity[sign] 351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(sign, '9'*context.prec, 352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context.Emax-context.prec+1) 353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sign == 1: 354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context.rounding == ROUND_FLOOR: 355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _SignedInfinity[sign] 356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(sign, '9'*context.prec, 357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context.Emax-context.prec+1) 358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Underflow(Inexact, Rounded, Subnormal): 361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Numerical underflow with result rounded to 0. 362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This occurs and signals underflow if a result is inexact and the 364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep adjusted exponent of the result would be smaller (more negative) than 365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the smallest value that can be handled by the implementation (the value 366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Emin). That is, the result is both inexact and subnormal. 367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The result after an underflow will be a subnormal number rounded, if 369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep necessary, so that its exponent is not less than Etiny. This may result 370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep in 0 with the sign of the intermediate result and an exponent of Etiny. 371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep In all cases, Inexact, Rounded, and Subnormal will also be raised. 373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# List of public traps and flags 376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded, 377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Underflow, InvalidOperation, Subnormal] 378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Map conditions (per the spec) to signals 380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_condition_map = {ConversionSyntax:InvalidOperation, 381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep DivisionImpossible:InvalidOperation, 382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep DivisionUndefined:InvalidOperation, 383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep InvalidContext:InvalidOperation} 384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### Context Functions ################################################## 386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# The getcontext() and setcontext() function manage access to a thread-local 388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# current context. Py2.4 offers direct support for thread locals. If that 389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# is not available, use threading.currentThread() which is slower but will 390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# work for older Pythons. If threads are not part of the build, create a 391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# mock threading object with threading.local() returning the module namespace. 392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoeptry: 394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep import threading 395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepexcept ImportError: 396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Python was compiled without threads; create a mock object instead 397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep import sys 398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep class MockThreading(object): 399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def local(self, sys=sys): 400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return sys.modules[__name__] 401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep threading = MockThreading() 402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del sys, MockThreading 403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoeptry: 405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep threading.local 406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepexcept AttributeError: 408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # To fix reloading, force it to create a new context 410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Old contexts have different exceptions in their dicts, making problems. 411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if hasattr(threading.currentThread(), '__decimal_context__'): 412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del threading.currentThread().__decimal_context__ 413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def setcontext(context): 415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Set this thread's context to context.""" 416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context in (DefaultContext, BasicContext, ExtendedContext): 417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = context.copy() 418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context.clear_flags() 419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep threading.currentThread().__decimal_context__ = context 420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def getcontext(): 422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns this thread's context. 423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If this thread does not yet have a context, returns 425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a new context and sets this thread's context. 426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep New contexts are copies of DefaultContext. 427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return threading.currentThread().__decimal_context__ 430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep except AttributeError: 431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = Context() 432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep threading.currentThread().__decimal_context__ = context 433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context 434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepelse: 436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep local = threading.local() 438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if hasattr(local, '__decimal_context__'): 439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del local.__decimal_context__ 440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def getcontext(_local=local): 442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns this thread's context. 443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If this thread does not yet have a context, returns 445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a new context and sets this thread's context. 446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep New contexts are copies of DefaultContext. 447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _local.__decimal_context__ 450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep except AttributeError: 451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = Context() 452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep _local.__decimal_context__ = context 453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context 454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def setcontext(context, _local=local): 456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Set this thread's context to context.""" 457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context in (DefaultContext, BasicContext, ExtendedContext): 458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = context.copy() 459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context.clear_flags() 460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep _local.__decimal_context__ = context 461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del threading, local # Don't contaminate the namespace 463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef localcontext(ctx=None): 465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return a context manager for a copy of the supplied context 466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Uses a copy of the current context if no context is specified 468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The returned context manager creates a local decimal context 469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep in a with statement: 470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def sin(x): 471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep with localcontext() as ctx: 472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ctx.prec += 2 473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Rest of sin calculation algorithm 474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # uses a precision 2 greater than normal 475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return +s # Convert result to normal precision 476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def sin(x): 478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep with localcontext(ExtendedContext): 479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Rest of sin calculation algorithm 480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # uses the Extended Context from the 481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # General Decimal Arithmetic Specification 482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return +s # Convert result to normal context 483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> setcontext(DefaultContext) 485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> print getcontext().prec 486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 28 487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> with localcontext(): 488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ... ctx = getcontext() 489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ... ctx.prec += 2 490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ... print ctx.prec 491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ... 492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 30 493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> with localcontext(ExtendedContext): 494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ... print getcontext().prec 495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ... 496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 9 497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> print getcontext().prec 498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 28 499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ctx is None: ctx = getcontext() 501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _ContextManager(ctx) 502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### Decimal class ####################################################### 505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Decimal(object): 507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Floating point class for decimal arithmetic.""" 508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep __slots__ = ('_exp','_int','_sign', '_is_special') 510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Generally, the value of the Decimal instance is given by 511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # (-1)**_sign * _int * 10**_exp 512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Special values are signified by _is_special == True 513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # We're immutable, so use __new__ not __init__ 515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __new__(cls, value="0", context=None): 516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Create a decimal point instance. 517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> Decimal('3.14') # string input 519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3.14') 520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> Decimal((0, (3, 1, 4), -2)) # tuple (sign, digit_tuple, exponent) 521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3.14') 522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> Decimal(314) # int or long 523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('314') 524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> Decimal(Decimal(314)) # another decimal instance 525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('314') 526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> Decimal(' 3.14 \\n') # leading and trailing whitespace okay 527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3.14') 528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Note that the coefficient, self._int, is actually stored as 531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # a string rather than as a tuple of digits. This speeds up 532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the "digits to integer" and "integer to digits" conversions 533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # that are used in almost every arithmetic operation on 534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Decimals. This is an internal detail: the as_tuple function 535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # and the Decimal constructor still deal with tuples of 536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # digits. 537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self = object.__new__(cls) 539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # From a string 541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # REs insist on real strings, so we can too. 542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if isinstance(value, basestring): 543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = _parser(value.strip()) 544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if m is None: 545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(ConversionSyntax, 548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "Invalid literal for Decimal: %r" % value) 549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if m.group('sign') == "-": 551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._sign = 1 552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._sign = 0 554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep intpart = m.group('int') 555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if intpart is not None: 556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # finite number 557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fracpart = m.group('frac') or '' 558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = int(m.group('exp') or '0') 559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._int = str(int(intpart+fracpart)) 560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._exp = exp - len(fracpart) 561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._is_special = False 562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep diag = m.group('diag') 564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if diag is not None: 565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # NaN 566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._int = str(int(diag or '0')).lstrip('0') 567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if m.group('signal'): 568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._exp = 'N' 569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._exp = 'n' 571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # infinity 573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._int = '0' 574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._exp = 'F' 575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._is_special = True 576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self 577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # From an integer 579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if isinstance(value, (int,long)): 580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if value >= 0: 581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._sign = 0 582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._sign = 1 584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._exp = 0 585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._int = str(abs(value)) 586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._is_special = False 587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self 588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # From another decimal 590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if isinstance(value, Decimal): 591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._exp = value._exp 592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._sign = value._sign 593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._int = value._int 594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._is_special = value._is_special 595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self 596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # From an internal working value 598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if isinstance(value, _WorkRep): 599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._sign = value.sign 600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._int = str(value.int) 601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._exp = int(value.exp) 602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._is_special = False 603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self 604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # tuple/list conversion (possibly from as_tuple()) 606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if isinstance(value, (list,tuple)): 607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if len(value) != 3: 608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError('Invalid tuple size in creation of Decimal ' 609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'from list or tuple. The list or tuple ' 610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'should have exactly three elements.') 611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # process sign. The isinstance test rejects floats 612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not (isinstance(value[0], (int, long)) and value[0] in (0,1)): 613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError("Invalid sign. The first value in the tuple " 614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "should be an integer; either 0 for a " 615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "positive number or 1 for a negative number.") 616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._sign = value[0] 617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if value[2] == 'F': 618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # infinity: value[1] is ignored 619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._int = '0' 620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._exp = value[2] 621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._is_special = True 622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # process and validate the digits in value[1] 624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep digits = [] 625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for digit in value[1]: 626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if isinstance(digit, (int, long)) and 0 <= digit <= 9: 627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # skip leading zeros 628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if digits or digit != 0: 629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep digits.append(digit) 630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError("The second value in the tuple must " 632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "be composed of integers in the range " 633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "0 through 9.") 634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if value[2] in ('n', 'N'): 635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # NaN: digits form the diagnostic 636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._int = ''.join(map(str, digits)) 637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._exp = value[2] 638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._is_special = True 639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif isinstance(value[2], (int, long)): 640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # finite number: digits give the coefficient 641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._int = ''.join(map(str, digits or [0])) 642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._exp = value[2] 643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._is_special = False 644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError("The third value in the tuple must " 646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "be an integer, or one of the " 647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "strings 'F', 'n', 'N'.") 648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self 649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if isinstance(value, float): 651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep value = Decimal.from_float(value) 652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._exp = value._exp 653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._sign = value._sign 654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._int = value._int 655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._is_special = value._is_special 656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self 657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise TypeError("Cannot convert %r to Decimal" % value) 659edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 660edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # @classmethod, but @decorator is not valid Python 2.3 syntax, so 661edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # don't use it (see notes on Py2.3 compatibility at top of file) 662edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def from_float(cls, f): 663edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Converts a float to a decimal number, exactly. 664edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 665edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Note that Decimal.from_float(0.1) is not the same as Decimal('0.1'). 666edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Since 0.1 is not exactly representable in binary floating point, the 667edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep value is stored as the nearest representable value which is 668edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 0x1.999999999999ap-4. The exact equivalent of the value in decimal 669edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep is 0.1000000000000000055511151231257827021181583404541015625. 670edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 671edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> Decimal.from_float(0.1) 672edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.1000000000000000055511151231257827021181583404541015625') 673edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> Decimal.from_float(float('nan')) 674edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('NaN') 675edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> Decimal.from_float(float('inf')) 676edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('Infinity') 677edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> Decimal.from_float(-float('inf')) 678edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-Infinity') 679edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> Decimal.from_float(-0.0) 680edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-0') 681edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 682edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 683edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if isinstance(f, (int, long)): # handle integer inputs 684edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return cls(f) 685edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if _math.isinf(f) or _math.isnan(f): # raises TypeError if not a float 686edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return cls(repr(f)) 687edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if _math.copysign(1.0, f) == 1.0: 688edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = 0 689edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 690edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = 1 691edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep n, d = abs(f).as_integer_ratio() 692edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep k = d.bit_length() - 1 693edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result = _dec_from_triple(sign, str(n*5**k), -k) 694edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if cls is Decimal: 695edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return result 696edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 697edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return cls(result) 698edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep from_float = classmethod(from_float) 699edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 700edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _isnan(self): 701edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns whether the number is not actually one. 702edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 703edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 0 if a number 704edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1 if NaN 705edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2 if sNaN 706edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 707edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special: 708edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = self._exp 709edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if exp == 'n': 710edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 1 711edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif exp == 'N': 712edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 2 713edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 0 714edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 715edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _isinfinity(self): 716edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns whether the number is infinite 717edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 718edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 0 if finite or not a number 719edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1 if +INF 720edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -1 if -INF 721edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 722edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._exp == 'F': 723edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign: 724edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return -1 725edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 1 726edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 0 727edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 728edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _check_nans(self, other=None, context=None): 729edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns whether the number is not actually one. 730edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 731edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self, other are sNaN, signal 732edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self, other are NaN return nan 733edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 0 734edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 735edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Done before operations. 736edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 737edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 738edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self_is_nan = self._isnan() 739edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is None: 740edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other_is_nan = False 741edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 742edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other_is_nan = other._isnan() 743edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 744edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_is_nan or other_is_nan: 745edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 746edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 747edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 748edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_is_nan == 2: 749edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 'sNaN', 750edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self) 751edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other_is_nan == 2: 752edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 'sNaN', 753edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other) 754edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_is_nan: 755edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._fix_nan(context) 756edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 757edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other._fix_nan(context) 758edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 0 759edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 760edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _compare_check_nans(self, other, context): 761edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Version of _check_nans used for the signaling comparisons 762edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep compare_signal, __le__, __lt__, __ge__, __gt__. 763edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 764edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Signal InvalidOperation if either self or other is a (quiet 765edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep or signaling) NaN. Signaling NaNs take precedence over quiet 766edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep NaNs. 767edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 768edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Return 0 if neither operand is a NaN. 769edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 770edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 771edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 772edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 773edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 774edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or other._is_special: 775edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self.is_snan(): 776edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 777edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'comparison involving sNaN', 778edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self) 779edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif other.is_snan(): 780edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 781edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'comparison involving sNaN', 782edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other) 783edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif self.is_qnan(): 784edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 785edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'comparison involving NaN', 786edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self) 787edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif other.is_qnan(): 788edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 789edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'comparison involving NaN', 790edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other) 791edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 0 792edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 793edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __nonzero__(self): 794edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if self is nonzero; otherwise return False. 795edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 796edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep NaNs and infinities are considered nonzero. 797edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 798edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._is_special or self._int != '0' 799edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 800edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _cmp(self, other): 801edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compare the two non-NaN decimal instances self and other. 802edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 803edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Returns -1 if self < other, 0 if self == other and 1 804edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self > other. This routine is for internal use only.""" 805edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 806edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or other._is_special: 807edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self_inf = self._isinfinity() 808edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other_inf = other._isinfinity() 809edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_inf == other_inf: 810edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 0 811edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif self_inf < other_inf: 812edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return -1 813edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 814edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 1 815edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 816edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # check for zeros; Decimal('0') == Decimal('-0') 817edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 818edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not other: 819edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 0 820edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 821edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return -((-1)**other._sign) 822edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not other: 823edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return (-1)**self._sign 824edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 825edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # If different signs, neg one is less 826edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._sign < self._sign: 827edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return -1 828edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign < other._sign: 829edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 1 830edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 831edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self_adjusted = self.adjusted() 832edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other_adjusted = other.adjusted() 833edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_adjusted == other_adjusted: 834edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self_padded = self._int + '0'*(self._exp - other._exp) 835edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other_padded = other._int + '0'*(other._exp - self._exp) 836edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_padded == other_padded: 837edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 0 838edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif self_padded < other_padded: 839edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return -(-1)**self._sign 840edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 841edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return (-1)**self._sign 842edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif self_adjusted > other_adjusted: 843edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return (-1)**self._sign 844edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: # self_adjusted < other_adjusted 845edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return -((-1)**self._sign) 846edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 847edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Note: The Decimal standard doesn't cover rich comparisons for 848edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Decimals. In particular, the specification is silent on the 849edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # subject of what should happen for a comparison involving a NaN. 850edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # We take the following approach: 851edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 852edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # == comparisons involving a quiet NaN always return False 853edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # != comparisons involving a quiet NaN always return True 854edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # == or != comparisons involving a signaling NaN signal 855edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # InvalidOperation, and return False or True as above if the 856edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # InvalidOperation is not trapped. 857edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # <, >, <= and >= comparisons involving a (quiet or signaling) 858edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # NaN signal InvalidOperation, and return False if the 859edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # InvalidOperation is not trapped. 860edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 861edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # This behavior is designed to conform as closely as possible to 862edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # that specified by IEEE 754. 863edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 864edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __eq__(self, other, context=None): 865edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, allow_float=True) 866edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 867edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 868edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._check_nans(other, context): 869edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return False 870edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._cmp(other) == 0 871edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 872edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __ne__(self, other, context=None): 873edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, allow_float=True) 874edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 875edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 876edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._check_nans(other, context): 877edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return True 878edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._cmp(other) != 0 879edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 880edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __lt__(self, other, context=None): 881edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, allow_float=True) 882edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 883edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 884edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._compare_check_nans(other, context) 885edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 886edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return False 887edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._cmp(other) < 0 888edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 889edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __le__(self, other, context=None): 890edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, allow_float=True) 891edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 892edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 893edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._compare_check_nans(other, context) 894edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 895edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return False 896edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._cmp(other) <= 0 897edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 898edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __gt__(self, other, context=None): 899edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, allow_float=True) 900edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 901edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 902edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._compare_check_nans(other, context) 903edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 904edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return False 905edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._cmp(other) > 0 906edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 907edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __ge__(self, other, context=None): 908edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, allow_float=True) 909edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 910edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 911edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._compare_check_nans(other, context) 912edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 913edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return False 914edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._cmp(other) >= 0 915edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 916edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def compare(self, other, context=None): 917edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compares one to another. 918edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 919edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -1 => a < b 920edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 0 => a = b 921edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1 => a > b 922edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep NaN => one is NaN 923edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Like __cmp__, but returns Decimal instances. 924edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 925edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 926edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 927edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Compare(NaN, NaN) = NaN 928edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if (self._is_special or other and other._is_special): 929edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(other, context) 930edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 931edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 932edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 933edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self._cmp(other)) 934edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 935edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __hash__(self): 936edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """x.__hash__() <==> hash(x)""" 937edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Decimal integers must hash the same as the ints 938edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 939edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # The hash of a nonspecial noninteger Decimal must depend only 940edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # on the value of that Decimal, and not on its representation. 941edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # For example: hash(Decimal('100E-1')) == hash(Decimal('10')). 942edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 943edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Equality comparisons involving signaling nans can raise an 944edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exception; since equality checks are implicitly and 945edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # unpredictably used when checking set and dict membership, we 946edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # prevent signaling nans from being used as set elements or 947edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # dict keys by making __hash__ raise an exception. 948edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special: 949edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self.is_snan(): 950edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise TypeError('Cannot hash a signaling NaN value.') 951edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif self.is_nan(): 952edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 0 to match hash(float('nan')) 953edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 0 954edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 955edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # values chosen to match hash(float('inf')) and 956edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # hash(float('-inf')). 957edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign: 958edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return -271828 959edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 960edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 314159 961edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 962edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # In Python 2.7, we're allowing comparisons (but not 963edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # arithmetic operations) between floats and Decimals; so if 964edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # a Decimal instance is exactly representable as a float then 965edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # its hash should match that of the float. 966edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self_as_float = float(self) 967edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if Decimal.from_float(self_as_float) == self: 968edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return hash(self_as_float) 969edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 970edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinteger(): 971edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op = _WorkRep(self.to_integral_value()) 972edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # to make computation feasible for Decimals with large 973edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exponent, we use the fact that hash(n) == hash(m) for 974edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # any two nonzero integers n and m such that (i) n and m 975edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # have the same sign, and (ii) n is congruent to m modulo 976edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 2**64-1. So we can replace hash((-1)**s*c*10**e) with 977edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # hash((-1)**s*c*pow(10, e, 2**64-1). 978edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return hash((-1)**op.sign*op.int*pow(10, op.exp, 2**64-1)) 979edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # The value of a nonzero nonspecial Decimal instance is 980edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # faithfully represented by the triple consisting of its sign, 981edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # its adjusted exponent, and its coefficient with trailing 982edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # zeros removed. 983edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return hash((self._sign, 984edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._exp+len(self._int), 985edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._int.rstrip('0'))) 986edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 987edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def as_tuple(self): 988edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Represents the number as a triple tuple. 989edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 990edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep To show the internals exactly as they are. 991edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 992edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return DecimalTuple(self._sign, tuple(map(int, self._int)), self._exp) 993edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 994edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __repr__(self): 995edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Represents the number as an instance of Decimal.""" 996edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Invariant: eval(repr(d)) == d 997edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return "Decimal('%s')" % str(self) 998edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 999edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __str__(self, eng=False, context=None): 1000edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return string representation of the number in scientific notation. 1001edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1002edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Captures all of the information in the underlying representation. 1003edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1004edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1005edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = ['', '-'][self._sign] 1006edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special: 1007edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._exp == 'F': 1008edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return sign + 'Infinity' 1009edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif self._exp == 'n': 1010edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return sign + 'NaN' + self._int 1011edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: # self._exp == 'N' 1012edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return sign + 'sNaN' + self._int 1013edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1014edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # number of digits of self._int to left of decimal point 1015edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep leftdigits = self._exp + len(self._int) 1016edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1017edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # dotplace is number of digits of self._int to the left of the 1018edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # decimal point in the mantissa of the output string (that is, 1019edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # after adjusting the exponent) 1020edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._exp <= 0 and leftdigits > -6: 1021edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # no exponent required 1022edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dotplace = leftdigits 1023edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif not eng: 1024edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # usual scientific notation: 1 digit on left of the point 1025edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dotplace = 1 1026edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif self._int == '0': 1027edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # engineering notation, zero 1028edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dotplace = (leftdigits + 1) % 3 - 1 1029edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1030edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # engineering notation, nonzero 1031edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dotplace = (leftdigits - 1) % 3 + 1 1032edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1033edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if dotplace <= 0: 1034edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep intpart = '0' 1035edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fracpart = '.' + '0'*(-dotplace) + self._int 1036edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif dotplace >= len(self._int): 1037edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep intpart = self._int+'0'*(dotplace-len(self._int)) 1038edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fracpart = '' 1039edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1040edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep intpart = self._int[:dotplace] 1041edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fracpart = '.' + self._int[dotplace:] 1042edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if leftdigits == dotplace: 1043edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = '' 1044edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1045edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 1046edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 1047edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = ['e', 'E'][context.capitals] + "%+d" % (leftdigits-dotplace) 1048edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1049edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return sign + intpart + fracpart + exp 1050edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1051edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def to_eng_string(self, context=None): 1052edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Convert to engineering-type string. 1053edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1054edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Engineering notation has an exponent which is a multiple of 3, so there 1055edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep are up to 3 digits left of the decimal place. 1056edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1057edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Same rules for when in exponential and when as a value as in __str__. 1058edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1059edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self.__str__(eng=True, context=context) 1060edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1061edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __neg__(self, context=None): 1062edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns a copy with the sign switched. 1063edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1064edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Rounds, if it has reason. 1065edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1066edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special: 1067edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(context=context) 1068edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 1069edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1070edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1071edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 1072edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 1073edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1074edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self and context.rounding != ROUND_FLOOR: 1075edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # -Decimal('0') is Decimal('0'), not Decimal('-0'), except 1076edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # in ROUND_FLOOR rounding mode. 1077edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self.copy_abs() 1078edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1079edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self.copy_negate() 1080edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1081edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans._fix(context) 1082edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1083edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __pos__(self, context=None): 1084edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns a copy, unless it is a sNaN. 1085edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1086edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Rounds the number (if more then precision digits) 1087edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1088edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special: 1089edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(context=context) 1090edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 1091edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1092edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1093edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 1094edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 1095edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1096edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self and context.rounding != ROUND_FLOOR: 1097edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # + (-0) = 0, except in ROUND_FLOOR rounding mode. 1098edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self.copy_abs() 1099edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = Decimal(self) 1101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans._fix(context) 1103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __abs__(self, round=True, context=None): 1105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the absolute value of self. 1106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If the keyword argument 'round' is false, do not round. The 1108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep expression self.__abs__(round=False) is equivalent to 1109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.copy_abs(). 1110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not round: 1112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self.copy_abs() 1113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special: 1115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(context=context) 1116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 1117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign: 1120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self.__neg__(context=context) 1121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self.__pos__(context=context) 1123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __add__(self, other, context=None): 1127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns self + other. 1128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -INF + INF (or the reverse) cause InvalidOperation errors. 1130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other) 1132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 1133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 1134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 1136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 1137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or other._is_special: 1139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(other, context) 1140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 1141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity(): 1144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # If both INF, same sign => same as both, opposite => error. 1145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign != other._sign and other._isinfinity(): 1146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, '-INF + INF') 1147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 1148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._isinfinity(): 1149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(other) # Can't both be infinity here 1150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = min(self._exp, other._exp) 1152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep negativezero = 0 1153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context.rounding == ROUND_FLOOR and self._sign != other._sign: 1154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # If the answer is 0, the sign should be negative, in this case. 1155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep negativezero = 1 1156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self and not other: 1158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = min(self._sign, other._sign) 1159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if negativezero: 1160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = 1 1161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(sign, '0', exp) 1162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(context) 1163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 1165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = max(exp, other._exp - context.prec-1) 1166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = other._rescale(exp, context.rounding) 1167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(context) 1168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not other: 1170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = max(exp, self._exp - context.prec-1) 1171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._rescale(exp, context.rounding) 1172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(context) 1173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op1 = _WorkRep(self) 1176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op2 = _WorkRep(other) 1177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op1, op2 = _normalize(op1, op2, context.prec) 1178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result = _WorkRep() 1180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if op1.sign != op2.sign: 1181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Equal and opposite 1182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if op1.int == op2.int: 1183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(negativezero, '0', exp) 1184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(context) 1185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if op1.int < op2.int: 1187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op1, op2 = op2, op1 1188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # OK, now abs(op1) > abs(op2) 1189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if op1.sign == 1: 1190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result.sign = 1 1191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op1.sign, op2.sign = op2.sign, op1.sign 1192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result.sign = 0 1194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # So we know the sign, and op1 > 0. 1195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif op1.sign == 1: 1196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result.sign = 1 1197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op1.sign, op2.sign = (0, 0) 1198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result.sign = 0 1200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Now, op1 > abs(op2) > 0 1201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if op2.sign == 0: 1203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result.int = op1.int + op2.int 1204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result.int = op1.int - op2.int 1206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result.exp = op1.exp 1208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = Decimal(result) 1209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(context) 1210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep __radd__ = __add__ 1213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __sub__(self, other, context=None): 1215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return self - other""" 1216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other) 1217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 1218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 1219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or other._is_special: 1221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(other, context=context) 1222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 1223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # self - other is computed as self + other.copy_negate() 1226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self.__add__(other.copy_negate(), context=context) 1227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __rsub__(self, other, context=None): 1229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return other - self""" 1230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other) 1231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 1232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 1233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other.__sub__(self, context=context) 1235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __mul__(self, other, context=None): 1237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return self * other. 1238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (+-) INF * 0 (or its reverse) raise InvalidOperation. 1240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other) 1242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 1243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 1244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 1246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 1247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep resultsign = self._sign ^ other._sign 1249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or other._is_special: 1251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(other, context) 1252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 1253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity(): 1256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not other: 1257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, '(+-)INF * 0') 1258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _SignedInfinity[resultsign] 1259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._isinfinity(): 1261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 1262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, '0 * (+-)INF') 1263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _SignedInfinity[resultsign] 1264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep resultexp = self._exp + other._exp 1266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Special case for multiplying by zero 1268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self or not other: 1269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(resultsign, '0', resultexp) 1270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Fixing in case the exponent is out of bounds 1271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(context) 1272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Special case for multiplying by power of 10 1275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._int == '1': 1276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(resultsign, other._int, resultexp) 1277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(context) 1278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._int == '1': 1280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(resultsign, self._int, resultexp) 1281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(context) 1282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op1 = _WorkRep(self) 1285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op2 = _WorkRep(other) 1286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(resultsign, str(op1.int * op2.int), resultexp) 1288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(context) 1289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep __rmul__ = __mul__ 1292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __truediv__(self, other, context=None): 1294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return self / other.""" 1295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other) 1296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 1297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return NotImplemented 1298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 1300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 1301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = self._sign ^ other._sign 1303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or other._is_special: 1305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(other, context) 1306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 1307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity() and other._isinfinity(): 1310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF') 1311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity(): 1313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _SignedInfinity[sign] 1314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._isinfinity(): 1316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Clamped, 'Division by infinity') 1317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(sign, '0', context.Etiny()) 1318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Special cases for zeroes 1320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not other: 1321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 1322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(DivisionUndefined, '0 / 0') 1323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(DivisionByZero, 'x / 0', sign) 1324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 1326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = self._exp - other._exp 1327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff = 0 1328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # OK, so neither = 0, INF or NaN 1330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep shift = len(other._int) - len(self._int) + context.prec + 1 1331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = self._exp - other._exp - shift 1332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op1 = _WorkRep(self) 1333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op2 = _WorkRep(other) 1334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if shift >= 0: 1335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff, remainder = divmod(op1.int * 10**shift, op2.int) 1336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff, remainder = divmod(op1.int, op2.int * 10**-shift) 1338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if remainder: 1339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # result is not exact; adjust to ensure correct rounding 1340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if coeff % 5 == 0: 1341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff += 1 1342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # result is exact; get as close to ideal exponent as possible 1344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ideal_exp = self._exp - other._exp 1345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while exp < ideal_exp and coeff % 10 == 0: 1346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff //= 10 1347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp += 1 1348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(sign, str(coeff), exp) 1350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans._fix(context) 1351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _divide(self, other, context): 1353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return (self // other, self % other), to context.prec precision. 1354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Assumes that neither self nor other is a NaN, that self is not 1356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep infinite and that other is nonzero. 1357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = self._sign ^ other._sign 1359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._isinfinity(): 1360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ideal_exp = self._exp 1361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ideal_exp = min(self._exp, other._exp) 1363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep expdiff = self.adjusted() - other.adjusted() 1365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self or other._isinfinity() or expdiff <= -2: 1366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return (_dec_from_triple(sign, '0', 0), 1367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._rescale(ideal_exp, context.rounding)) 1368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if expdiff <= context.prec: 1369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op1 = _WorkRep(self) 1370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op2 = _WorkRep(other) 1371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if op1.exp >= op2.exp: 1372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op1.int *= 10**(op1.exp - op2.exp) 1373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op2.int *= 10**(op2.exp - op1.exp) 1375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep q, r = divmod(op1.int, op2.int) 1376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if q < 10**context.prec: 1377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return (_dec_from_triple(sign, str(q), 0), 1378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep _dec_from_triple(self._sign, str(r), ideal_exp)) 1379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Here the quotient is too large to be representable 1381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = context._raise_error(DivisionImpossible, 1382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'quotient too large in //, % or divmod') 1383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans, ans 1384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __rtruediv__(self, other, context=None): 1386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Swaps self/other and returns __truediv__.""" 1387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other) 1388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 1389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 1390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other.__truediv__(self, context=context) 1391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep __div__ = __truediv__ 1393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep __rdiv__ = __rtruediv__ 1394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __divmod__(self, other, context=None): 1396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Return (self // other, self % other) 1398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other) 1400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 1401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 1402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 1404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 1405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(other, context) 1407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 1408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return (ans, ans) 1409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = self._sign ^ other._sign 1411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity(): 1412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._isinfinity(): 1413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = context._raise_error(InvalidOperation, 'divmod(INF, INF)') 1414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans, ans 1415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return (_SignedInfinity[sign], 1417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(InvalidOperation, 'INF % x')) 1418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not other: 1420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 1421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = context._raise_error(DivisionUndefined, 'divmod(0, 0)') 1422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans, ans 1423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return (context._raise_error(DivisionByZero, 'x // 0', sign), 1425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(InvalidOperation, 'x % 0')) 1426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep quotient, remainder = self._divide(other, context) 1428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep remainder = remainder._fix(context) 1429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return quotient, remainder 1430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __rdivmod__(self, other, context=None): 1432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Swaps self/other and returns __divmod__.""" 1433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other) 1434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 1435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 1436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other.__divmod__(self, context=context) 1437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __mod__(self, other, context=None): 1439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self % other 1441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other) 1443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 1444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 1445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 1447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 1448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(other, context) 1450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 1451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity(): 1454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 'INF % x') 1455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif not other: 1456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self: 1457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 'x % 0') 1458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(DivisionUndefined, '0 % 0') 1460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep remainder = self._divide(other, context)[1] 1462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep remainder = remainder._fix(context) 1463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return remainder 1464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __rmod__(self, other, context=None): 1466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Swaps self/other and returns __mod__.""" 1467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other) 1468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 1469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 1470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other.__mod__(self, context=context) 1471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def remainder_near(self, other, context=None): 1473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Remainder nearest to 0- abs(remainder-near) <= other/2 1475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 1477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 1478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 1480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(other, context) 1482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 1483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # self == +/-infinity -> InvalidOperation 1486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity(): 1487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 1488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'remainder_near(infinity, x)') 1489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # other == 0 -> either InvalidOperation or DivisionUndefined 1491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not other: 1492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self: 1493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 1494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'remainder_near(x, 0)') 1495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(DivisionUndefined, 1497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'remainder_near(0, 0)') 1498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # other = +/-infinity -> remainder = self 1500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._isinfinity(): 1501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = Decimal(self) 1502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans._fix(context) 1503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # self = 0 -> remainder = self, with ideal exponent 1505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ideal_exponent = min(self._exp, other._exp) 1506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 1507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(self._sign, '0', ideal_exponent) 1508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans._fix(context) 1509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # catch most cases of large or small quotient 1511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep expdiff = self.adjusted() - other.adjusted() 1512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if expdiff >= context.prec + 1: 1513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # expdiff >= prec+1 => abs(self/other) > 10**prec 1514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(DivisionImpossible) 1515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if expdiff <= -2: 1516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # expdiff <= -2 => abs(self/other) < 0.1 1517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._rescale(ideal_exponent, context.rounding) 1518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans._fix(context) 1519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # adjust both arguments to have the same exponent, then divide 1521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op1 = _WorkRep(self) 1522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op2 = _WorkRep(other) 1523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if op1.exp >= op2.exp: 1524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op1.int *= 10**(op1.exp - op2.exp) 1525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op2.int *= 10**(op2.exp - op1.exp) 1527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep q, r = divmod(op1.int, op2.int) 1528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # remainder is r*10**ideal_exponent; other is +/-op2.int * 1529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 10**ideal_exponent. Apply correction to ensure that 1530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # abs(remainder) <= abs(other)/2 1531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if 2*r + (q&1) > op2.int: 1532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r -= op2.int 1533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep q += 1 1534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if q >= 10**context.prec: 1536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(DivisionImpossible) 1537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # result has same sign as self unless r is negative 1539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = self._sign 1540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if r < 0: 1541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = 1-sign 1542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r = -r 1543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(sign, str(r), ideal_exponent) 1545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans._fix(context) 1546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __floordiv__(self, other, context=None): 1548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """self // other""" 1549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other) 1550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 1551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 1552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 1554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 1555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(other, context) 1557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 1558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity(): 1561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._isinfinity(): 1562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 'INF // INF') 1563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _SignedInfinity[self._sign ^ other._sign] 1565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not other: 1567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self: 1568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(DivisionByZero, 'x // 0', 1569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._sign ^ other._sign) 1570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(DivisionUndefined, '0 // 0') 1572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._divide(other, context)[0] 1574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __rfloordiv__(self, other, context=None): 1576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Swaps self/other and returns __floordiv__.""" 1577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other) 1578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 1579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 1580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other.__floordiv__(self, context=context) 1581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __float__(self): 1583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Float representation.""" 1584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isnan(): 1585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self.is_snan(): 1586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError("Cannot convert signaling NaN to float") 1587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = "-nan" if self._sign else "nan" 1588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = str(self) 1590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return float(s) 1591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __int__(self): 1593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Converts self to an int, truncating if necessary.""" 1594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special: 1595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isnan(): 1596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError("Cannot convert NaN to integer") 1597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif self._isinfinity(): 1598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise OverflowError("Cannot convert infinity to integer") 1599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = (-1)**self._sign 1600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._exp >= 0: 1601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return s*int(self._int)*10**self._exp 1602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return s*int(self._int[:self._exp] or '0') 1604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep __trunc__ = __int__ 1606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def real(self): 1608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self 1609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep real = property(real) 1610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def imag(self): 1612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(0) 1613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep imag = property(imag) 1614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def conjugate(self): 1616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self 1617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __complex__(self): 1619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return complex(float(self)) 1620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __long__(self): 1622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Converts to a long. 1623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Equivalent to long(int(self)) 1625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return long(self.__int__()) 1627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _fix_nan(self, context): 1629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Decapitate the payload of a NaN to fit the context""" 1630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep payload = self._int 1631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # maximum length of payload is precision if _clamp=0, 1633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # precision-1 if _clamp=1. 1634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep max_payload_len = context.prec - context._clamp 1635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if len(payload) > max_payload_len: 1636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep payload = payload[len(payload)-max_payload_len:].lstrip('0') 1637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(self._sign, payload, self._exp, True) 1638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 1639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _fix(self, context): 1641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Round if it is necessary to keep self within prec precision. 1642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Rounds and fixes the exponent. Does not raise on a sNaN. 1644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Arguments: 1646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self - Decimal instance 1647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context - context used. 1648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special: 1651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isnan(): 1652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # decapitate payload if necessary 1653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._fix_nan(context) 1654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # self is +/-Infinity; return unaltered 1656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 1657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # if self is zero then exponent should be between Etiny and 1659edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Emax if _clamp==0, and between Etiny and Etop if _clamp==1. 1660edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Etiny = context.Etiny() 1661edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Etop = context.Etop() 1662edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 1663edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp_max = [context.Emax, Etop][context._clamp] 1664edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep new_exp = min(max(self._exp, Etiny), exp_max) 1665edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if new_exp != self._exp: 1666edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Clamped) 1667edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(self._sign, '0', new_exp) 1668edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1669edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 1670edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1671edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exp_min is the smallest allowable exponent of the result, 1672edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # equal to max(self.adjusted()-context.prec+1, Etiny) 1673edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp_min = len(self._int) + self._exp - context.prec 1674edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if exp_min > Etop: 1675edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # overflow: exp_min > Etop iff self.adjusted() > Emax 1676edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = context._raise_error(Overflow, 'above Emax', self._sign) 1677edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Inexact) 1678edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Rounded) 1679edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1680edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1681edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self_is_subnormal = exp_min < Etiny 1682edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_is_subnormal: 1683edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp_min = Etiny 1684edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1685edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # round if self has too many digits 1686edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._exp < exp_min: 1687edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep digits = len(self._int) + self._exp - exp_min 1688edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if digits < 0: 1689edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self = _dec_from_triple(self._sign, '1', exp_min-1) 1690edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep digits = 0 1691edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rounding_method = self._pick_rounding_function[context.rounding] 1692edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep changed = rounding_method(self, digits) 1693edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff = self._int[:digits] or '0' 1694edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if changed > 0: 1695edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff = str(int(coeff)+1) 1696edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if len(coeff) > context.prec: 1697edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff = coeff[:-1] 1698edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp_min += 1 1699edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1700edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # check whether the rounding pushed the exponent out of range 1701edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if exp_min > Etop: 1702edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = context._raise_error(Overflow, 'above Emax', self._sign) 1703edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1704edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(self._sign, coeff, exp_min) 1705edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1706edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # raise the appropriate signals, taking care to respect 1707edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the precedence described in the specification 1708edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if changed and self_is_subnormal: 1709edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Underflow) 1710edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_is_subnormal: 1711edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Subnormal) 1712edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if changed: 1713edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Inexact) 1714edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Rounded) 1715edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not ans: 1716edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # raise Clamped on underflow to 0 1717edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Clamped) 1718edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 1719edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1720edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_is_subnormal: 1721edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Subnormal) 1722edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1723edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # fold down if _clamp == 1 and self has too few digits 1724edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context._clamp == 1 and self._exp > Etop: 1725edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Clamped) 1726edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self_padded = self._int + '0'*(self._exp - Etop) 1727edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(self._sign, self_padded, Etop) 1728edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1729edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # here self was representable to begin with; return unchanged 1730edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 1731edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1732edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # for each of the rounding functions below: 1733edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # self is a finite, nonzero Decimal 1734edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # prec is an integer satisfying 0 <= prec < len(self._int) 1735edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 1736edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # each function returns either -1, 0, or 1, as follows: 1737edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 1 indicates that self should be rounded up (away from zero) 1738edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 0 indicates that self should be truncated, and that all the 1739edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # digits to be truncated are zeros (so the value is unchanged) 1740edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # -1 indicates that there are nonzero digits to be truncated 1741edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1742edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _round_down(self, prec): 1743edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Also known as round-towards-0, truncate.""" 1744edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if _all_zeros(self._int, prec): 1745edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 0 1746edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1747edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return -1 1748edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1749edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _round_up(self, prec): 1750edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Rounds away from 0.""" 1751edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return -self._round_down(prec) 1752edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1753edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _round_half_up(self, prec): 1754edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Rounds 5 up (away from 0)""" 1755edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._int[prec] in '56789': 1756edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 1 1757edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif _all_zeros(self._int, prec): 1758edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 0 1759edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1760edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return -1 1761edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1762edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _round_half_down(self, prec): 1763edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Round 5 down""" 1764edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if _exact_half(self._int, prec): 1765edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return -1 1766edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1767edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._round_half_up(prec) 1768edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1769edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _round_half_even(self, prec): 1770edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Round 5 to even, rest to nearest.""" 1771edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if _exact_half(self._int, prec) and \ 1772edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (prec == 0 or self._int[prec-1] in '02468'): 1773edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return -1 1774edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1775edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._round_half_up(prec) 1776edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1777edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _round_ceiling(self, prec): 1778edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Rounds up (not away from 0 if negative.)""" 1779edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign: 1780edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._round_down(prec) 1781edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1782edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return -self._round_down(prec) 1783edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1784edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _round_floor(self, prec): 1785edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Rounds down (not towards 0 if negative)""" 1786edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self._sign: 1787edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._round_down(prec) 1788edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1789edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return -self._round_down(prec) 1790edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1791edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _round_05up(self, prec): 1792edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Round down unless digit prec-1 is 0 or 5.""" 1793edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if prec and self._int[prec-1] not in '05': 1794edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._round_down(prec) 1795edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1796edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return -self._round_down(prec) 1797edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1798edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep _pick_rounding_function = dict( 1799edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ROUND_DOWN = _round_down, 1800edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ROUND_UP = _round_up, 1801edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ROUND_HALF_UP = _round_half_up, 1802edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ROUND_HALF_DOWN = _round_half_down, 1803edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ROUND_HALF_EVEN = _round_half_even, 1804edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ROUND_CEILING = _round_ceiling, 1805edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ROUND_FLOOR = _round_floor, 1806edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ROUND_05UP = _round_05up, 1807edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ) 1808edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1809edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def fma(self, other, third, context=None): 1810edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Fused multiply-add. 1811edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1812edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Returns self*other+third with no rounding of the intermediate 1813edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep product self*other. 1814edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1815edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self and other are multiplied together, with no rounding of 1816edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the result. The third operand is then added to the result, 1817edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep and a single final rounding is performed. 1818edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 1819edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1820edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 1821edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1822edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute product; raise InvalidOperation if either operand is 1823edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # a signaling NaN or if the product is zero times infinity. 1824edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or other._is_special: 1825edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 1826edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 1827edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._exp == 'N': 1828edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 'sNaN', self) 1829edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._exp == 'N': 1830edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 'sNaN', other) 1831edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._exp == 'n': 1832edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep product = self 1833edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif other._exp == 'n': 1834edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep product = other 1835edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif self._exp == 'F': 1836edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not other: 1837edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 1838edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'INF * 0 in fma') 1839edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep product = _SignedInfinity[self._sign ^ other._sign] 1840edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif other._exp == 'F': 1841edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 1842edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 1843edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '0 * INF in fma') 1844edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep product = _SignedInfinity[self._sign ^ other._sign] 1845edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1846edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep product = _dec_from_triple(self._sign ^ other._sign, 1847edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep str(int(self._int) * int(other._int)), 1848edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._exp + other._exp) 1849edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1850edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep third = _convert_other(third, raiseit=True) 1851edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return product.__add__(third, context) 1852edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1853edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _power_modulo(self, other, modulo, context=None): 1854edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Three argument version of __pow__""" 1855edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1856edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # if can't convert other and modulo to Decimal, raise 1857edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # TypeError; there's no point returning NotImplemented (no 1858edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # equivalent of __rpow__ for three argument pow) 1859edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 1860edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep modulo = _convert_other(modulo, raiseit=True) 1861edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1862edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 1863edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 1864edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1865edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # deal with NaNs: if there are any sNaNs then first one wins, 1866edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # (i.e. behaviour for NaNs is identical to that of fma) 1867edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self_is_nan = self._isnan() 1868edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other_is_nan = other._isnan() 1869edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep modulo_is_nan = modulo._isnan() 1870edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_is_nan or other_is_nan or modulo_is_nan: 1871edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_is_nan == 2: 1872edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 'sNaN', 1873edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self) 1874edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other_is_nan == 2: 1875edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 'sNaN', 1876edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other) 1877edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if modulo_is_nan == 2: 1878edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 'sNaN', 1879edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep modulo) 1880edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_is_nan: 1881edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._fix_nan(context) 1882edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other_is_nan: 1883edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other._fix_nan(context) 1884edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return modulo._fix_nan(context) 1885edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1886edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # check inputs: we apply same restrictions as Python's pow() 1887edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not (self._isinteger() and 1888edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other._isinteger() and 1889edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep modulo._isinteger()): 1890edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 1891edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'pow() 3rd argument not allowed ' 1892edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'unless all arguments are integers') 1893edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other < 0: 1894edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 1895edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'pow() 2nd argument cannot be ' 1896edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'negative when 3rd argument specified') 1897edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not modulo: 1898edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 1899edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'pow() 3rd argument cannot be 0') 1900edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1901edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # additional restriction for decimal: the modulus must be less 1902edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # than 10**prec in absolute value 1903edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if modulo.adjusted() >= context.prec: 1904edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 1905edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'insufficient precision: pow() 3rd ' 1906edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'argument must not have more than ' 1907edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'precision digits') 1908edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1909edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # define 0**0 == NaN, for consistency with two-argument pow 1910edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # (even though it hurts!) 1911edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not other and not self: 1912edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 1913edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'at least one of pow() 1st argument ' 1914edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'and 2nd argument must be nonzero ;' 1915edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '0**0 is not defined') 1916edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1917edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute sign of result 1918edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._iseven(): 1919edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = 0 1920edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1921edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = self._sign 1922edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1923edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # convert modulo to a Python integer, and self and other to 1924edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Decimal integers (i.e. force their exponents to be >= 0) 1925edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep modulo = abs(int(modulo)) 1926edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep base = _WorkRep(self.to_integral_value()) 1927edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exponent = _WorkRep(other.to_integral_value()) 1928edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1929edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute result using integer pow() 1930edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep base = (base.int % modulo * pow(10, base.exp, modulo)) % modulo 1931edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for i in xrange(exponent.exp): 1932edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep base = pow(base, 10, modulo) 1933edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep base = pow(base, exponent.int, modulo) 1934edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1935edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(sign, str(base), 0) 1936edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1937edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _power_exact(self, other, p): 1938edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Attempt to compute self**other exactly. 1939edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1940edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Given Decimals self and other and an integer p, attempt to 1941edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep compute an exact result for the power self**other, with p 1942edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep digits of precision. Return None if self**other is not 1943edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exactly representable in p digits. 1944edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1945edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Assumes that elimination of special cases has already been 1946edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep performed: self and other must both be nonspecial; self must 1947edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep be positive and not numerically equal to 1; other must be 1948edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep nonzero. For efficiency, other._exp should not be too large, 1949edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep so that 10**abs(other._exp) is a feasible calculation.""" 1950edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1951edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # In the comments below, we write x for the value of self and y for the 1952edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # value of other. Write x = xc*10**xe and abs(y) = yc*10**ye, with xc 1953edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # and yc positive integers not divisible by 10. 1954edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1955edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # The main purpose of this method is to identify the *failure* 1956edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # of x**y to be exactly representable with as little effort as 1957edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # possible. So we look for cheap and easy tests that 1958edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # eliminate the possibility of x**y being exact. Only if all 1959edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # these tests are passed do we go on to actually compute x**y. 1960edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1961edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Here's the main idea. Express y as a rational number m/n, with m and 1962edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # n relatively prime and n>0. Then for x**y to be exactly 1963edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # representable (at *any* precision), xc must be the nth power of a 1964edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # positive integer and xe must be divisible by n. If y is negative 1965edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # then additionally xc must be a power of either 2 or 5, hence a power 1966edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # of 2**n or 5**n. 1967edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 1968edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # There's a limit to how small |y| can be: if y=m/n as above 1969edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # then: 1970edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 1971edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # (1) if xc != 1 then for the result to be representable we 1972edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # need xc**(1/n) >= 2, and hence also xc**|y| >= 2. So 1973edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # if |y| <= 1/nbits(xc) then xc < 2**nbits(xc) <= 1974edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 2**(1/|y|), hence xc**|y| < 2 and the result is not 1975edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # representable. 1976edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 1977edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # (2) if xe != 0, |xe|*(1/n) >= 1, so |xe|*|y| >= 1. Hence if 1978edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # |y| < 1/|xe| then the result is not representable. 1979edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 1980edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Note that since x is not equal to 1, at least one of (1) and 1981edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # (2) must apply. Now |y| < 1/nbits(xc) iff |yc|*nbits(xc) < 1982edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 10**-ye iff len(str(|yc|*nbits(xc)) <= -ye. 1983edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 1984edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # There's also a limit to how large y can be, at least if it's 1985edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # positive: the normalized result will have coefficient xc**y, 1986edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # so if it's representable then xc**y < 10**p, and y < 1987edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # p/log10(xc). Hence if y*log10(xc) >= p then the result is 1988edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # not exactly representable. 1989edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1990edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # if len(str(abs(yc*xe)) <= -ye then abs(yc*xe) < 10**-ye, 1991edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # so |y| < 1/xe and the result is not representable. 1992edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Similarly, len(str(abs(yc)*xc_bits)) <= -ye implies |y| 1993edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # < 1/nbits(xc). 1994edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1995edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep x = _WorkRep(self) 1996edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xc, xe = x.int, x.exp 1997edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while xc % 10 == 0: 1998edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xc //= 10 1999edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xe += 1 2000edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2001edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep y = _WorkRep(other) 2002edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep yc, ye = y.int, y.exp 2003edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while yc % 10 == 0: 2004edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep yc //= 10 2005edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ye += 1 2006edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2007edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # case where xc == 1: result is 10**(xe*y), with xe*y 2008edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # required to be an integer 2009edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if xc == 1: 2010edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xe *= yc 2011edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # result is now 10**(xe * 10**ye); xe * 10**ye must be integral 2012edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while xe % 10 == 0: 2013edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xe //= 10 2014edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ye += 1 2015edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ye < 0: 2016edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2017edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exponent = xe * 10**ye 2018edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if y.sign == 1: 2019edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exponent = -exponent 2020edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # if other is a nonnegative integer, use ideal exponent 2021edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._isinteger() and other._sign == 0: 2022edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ideal_exponent = self._exp*int(other) 2023edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep zeros = min(exponent-ideal_exponent, p-1) 2024edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2025edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep zeros = 0 2026edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(0, '1' + '0'*zeros, exponent-zeros) 2027edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2028edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # case where y is negative: xc must be either a power 2029edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # of 2 or a power of 5. 2030edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if y.sign == 1: 2031edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep last_digit = xc % 10 2032edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if last_digit in (2,4,6,8): 2033edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # quick test for power of 2 2034edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if xc & -xc != xc: 2035edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2036edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # now xc is a power of 2; e is its exponent 2037edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep e = _nbits(xc)-1 2038edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2039edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # We now have: 2040edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 2041edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # x = 2**e * 10**xe, e > 0, and y < 0. 2042edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 2043edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # The exact result is: 2044edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 2045edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # x**y = 5**(-e*y) * 10**(e*y + xe*y) 2046edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 2047edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # provided that both e*y and xe*y are integers. Note that if 2048edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 5**(-e*y) >= 10**p, then the result can't be expressed 2049edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exactly with p digits of precision. 2050edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 2051edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Using the above, we can guard against large values of ye. 2052edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 93/65 is an upper bound for log(10)/log(5), so if 2053edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 2054edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # ye >= len(str(93*p//65)) 2055edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 2056edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # then 2057edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 2058edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5), 2059edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 2060edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # so 5**(-e*y) >= 10**p, and the coefficient of the result 2061edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # can't be expressed in p digits. 2062edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2063edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # emax >= largest e such that 5**e < 10**p. 2064edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep emax = p*93//65 2065edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ye >= len(str(emax)): 2066edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2067edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2068edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Find -e*y and -xe*y; both must be integers 2069edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep e = _decimal_lshift_exact(e * yc, ye) 2070edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xe = _decimal_lshift_exact(xe * yc, ye) 2071edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if e is None or xe is None: 2072edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2073edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2074edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if e > emax: 2075edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2076edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xc = 5**e 2077edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2078edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif last_digit == 5: 2079edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # e >= log_5(xc) if xc is a power of 5; we have 2080edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # equality all the way up to xc=5**2658 2081edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep e = _nbits(xc)*28//65 2082edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xc, remainder = divmod(5**e, xc) 2083edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if remainder: 2084edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2085edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while xc % 5 == 0: 2086edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xc //= 5 2087edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep e -= 1 2088edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2089edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Guard against large values of ye, using the same logic as in 2090edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the 'xc is a power of 2' branch. 10/3 is an upper bound for 2091edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # log(10)/log(2). 2092edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep emax = p*10//3 2093edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ye >= len(str(emax)): 2094edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2095edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2096edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep e = _decimal_lshift_exact(e * yc, ye) 2097edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xe = _decimal_lshift_exact(xe * yc, ye) 2098edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if e is None or xe is None: 2099edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if e > emax: 2102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xc = 2**e 2104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if xc >= 10**p: 2108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xe = -e-xe 2110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(0, str(xc), xe) 2111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # now y is positive; find m and n such that y = m/n 2113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ye >= 0: 2114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m, n = yc*10**ye, 1 2115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if xe != 0 and len(str(abs(yc*xe))) <= -ye: 2117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xc_bits = _nbits(xc) 2119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if xc != 1 and len(str(abs(yc)*xc_bits)) <= -ye: 2120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m, n = yc, 10**(-ye) 2122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while m % 2 == n % 2 == 0: 2123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m //= 2 2124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep n //= 2 2125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while m % 5 == n % 5 == 0: 2126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m //= 5 2127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep n //= 5 2128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute nth root of xc*10**xe 2130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if n > 1: 2131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # if 1 < xc < 2**n then xc isn't an nth power 2132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if xc != 1 and xc_bits <= n: 2133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xe, rem = divmod(xe, n) 2136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if rem != 0: 2137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute nth root of xc using Newton's method 2140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = 1L << -(-_nbits(xc)//n) # initial estimate 2141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while True: 2142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep q, r = divmod(xc, a**(n-1)) 2143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if a <= q: 2144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep break 2145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = (a*(n-1) + q)//n 2147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not (a == q and r == 0): 2148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xc = a 2150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # now xc*10**xe is the nth root of the original xc*10**xe 2152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute mth power of xc*10**xe 2153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # if m > p*100//_log10_lb(xc) then m > p/log10(xc), hence xc**m > 2155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 10**p and the result is not representable. 2156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if xc > 1 and m > p*100//_log10_lb(xc): 2157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xc = xc**m 2159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xe *= m 2160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if xc > 10**p: 2161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None 2162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # by this point the result *is* exactly representable 2164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # adjust the exponent to get as close as possible to the ideal 2165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exponent, if necessary 2166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep str_xc = str(xc) 2167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._isinteger() and other._sign == 0: 2168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ideal_exponent = self._exp*int(other) 2169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep zeros = min(xe-ideal_exponent, p-len(str_xc)) 2170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep zeros = 0 2172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(0, str_xc+'0'*zeros, xe-zeros) 2173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __pow__(self, other, modulo=None, context=None): 2175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return self ** other [ % modulo]. 2176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep With two arguments, compute self**other. 2178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep With three arguments, compute (self**other) % modulo. For the 2180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep three argument form, the following restrictions on the 2181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep arguments hold: 2182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep - all three arguments must be integral 2184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep - other must be nonnegative 2185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep - either self or other (or both) must be nonzero 2186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep - modulo must be nonzero and must have at most p digits, 2187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep where p is the context precision. 2188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If any of these restrictions is violated the InvalidOperation 2190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep flag is raised. 2191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The result of pow(self, other, modulo) is identical to the 2193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result that would be obtained by computing (self**other) % 2194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep modulo with unbounded precision, but is computed more 2195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep efficiently. It is always exact. 2196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 2197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if modulo is not None: 2199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._power_modulo(other, modulo, context) 2200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other) 2202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 2203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 2204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 2206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 2207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # either argument is a NaN => result is NaN 2209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(other, context) 2210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 2211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 2212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 0**0 = NaN (!), x**0 = 1 for nonzero x (including +/-Infinity) 2214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not other: 2215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 2216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, '0 ** 0') 2217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _One 2219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # result has sign 1 iff self._sign is 1 and other is an odd integer 2221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result_sign = 0 2222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign == 1: 2223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._isinteger(): 2224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not other._iseven(): 2225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result_sign = 1 2226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # -ve**noninteger = NaN 2228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # (-0)**noninteger = 0**noninteger 2229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self: 2230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 2231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'x ** y with x negative and y not an integer') 2232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # negate self, without doing any unwanted rounding 2233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self = self.copy_negate() 2234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 0**(+ve or Inf)= 0; 0**(-ve or -Inf) = Infinity 2236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 2237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._sign == 0: 2238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(result_sign, '0', 0) 2239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _SignedInfinity[result_sign] 2241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Inf**(+ve or Inf) = Inf; Inf**(-ve or -Inf) = 0 2243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity(): 2244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._sign == 0: 2245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _SignedInfinity[result_sign] 2246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(result_sign, '0', 0) 2248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 1**other = 1, but the choice of exponent and the flags 2250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # depend on the exponent of self, and on whether other is a 2251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # positive integer, a negative integer, or neither 2252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self == _One: 2253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._isinteger(): 2254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exp = max(self._exp*max(int(other), 0), 2255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 1-context.prec) but evaluating int(other) directly 2256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # is dangerous until we know other is small (other 2257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # could be 1e999999999) 2258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._sign == 1: 2259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep multiplier = 0 2260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif other > context.prec: 2261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep multiplier = context.prec 2262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep multiplier = int(other) 2264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = self._exp * multiplier 2266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if exp < 1-context.prec: 2267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = 1-context.prec 2268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Rounded) 2269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Inexact) 2271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Rounded) 2272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = 1-context.prec 2273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(result_sign, '1'+'0'*-exp, exp) 2275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute adjusted exponent of self 2277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self_adj = self.adjusted() 2278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # self ** infinity is infinity if self > 1, 0 if self < 1 2280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # self ** -infinity is infinity if self < 1, 0 if self > 1 2281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._isinfinity(): 2282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if (other._sign == 0) == (self_adj < 0): 2283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(result_sign, '0', 0) 2284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _SignedInfinity[result_sign] 2286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # from here on, the result always goes through the call 2288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # to _fix at the end of this function. 2289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = None 2290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exact = False 2291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # crude test to catch cases of extreme overflow/underflow. If 2293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # log10(self)*other >= 10**bound and bound >= len(str(Emax)) 2294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # then 10**bound >= 10**len(str(Emax)) >= Emax+1 and hence 2295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # self**other >= 10**(Emax+1), so overflow occurs. The test 2296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # for underflow is similar. 2297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep bound = self._log10_exp_bound() + other.adjusted() 2298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if (self_adj >= 0) == (other._sign == 0): 2299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # self > 1 and other +ve, or self < 1 and other -ve 2300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # possibility of overflow 2301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if bound >= len(str(context.Emax)): 2302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(result_sign, '1', context.Emax+1) 2303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # self > 1 and other -ve, or self < 1 and other +ve 2305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # possibility of underflow to 0 2306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Etiny = context.Etiny() 2307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if bound >= len(str(-Etiny)): 2308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(result_sign, '1', Etiny-1) 2309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # try for an exact result with precision +1 2311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans is None: 2312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._power_exact(other, context.prec + 1) 2313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans is not None: 2314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if result_sign == 1: 2315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(1, ans._int, ans._exp) 2316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exact = True 2317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # usual case: inexact result, x**y computed directly as exp(y*log(x)) 2319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans is None: 2320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep p = context.prec 2321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep x = _WorkRep(self) 2322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xc, xe = x.int, x.exp 2323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep y = _WorkRep(other) 2324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep yc, ye = y.int, y.exp 2325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if y.sign == 1: 2326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep yc = -yc 2327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute correctly rounded result: start with precision +3, 2329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # then increase precision until result is unambiguously roundable 2330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep extra = 3 2331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while True: 2332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff, exp = _dpower(xc, xe, yc, ye, p+extra) 2333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if coeff % (5*10**(len(str(coeff))-p-1)): 2334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep break 2335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep extra += 3 2336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(result_sign, str(coeff), exp) 2338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # unlike exp, ln and log10, the power function respects the 2340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # rounding mode; no need to switch to ROUND_HALF_EVEN here 2341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # There's a difficulty here when 'other' is not an integer and 2343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the result is exact. In this case, the specification 2344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # requires that the Inexact flag be raised (in spite of 2345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exactness), but since the result is exact _fix won't do this 2346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # for us. (Correspondingly, the Underflow signal should also 2347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # be raised for subnormal results.) We can't directly raise 2348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # these signals either before or after calling _fix, since 2349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # that would violate the precedence for signals. So we wrap 2350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the ._fix call in a temporary context, and reraise 2351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # afterwards. 2352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if exact and not other._isinteger(): 2353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # pad with zeros up to length context.prec+1 if necessary; this 2354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # ensures that the Rounded signal will be raised. 2355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if len(ans._int) <= context.prec: 2356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep expdiff = context.prec + 1 - len(ans._int) 2357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(ans._sign, ans._int+'0'*expdiff, 2358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans._exp-expdiff) 2359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # create a copy of the current context, with cleared flags/traps 2361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep newcontext = context.copy() 2362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep newcontext.clear_flags() 2363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for exception in _signals: 2364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep newcontext.traps[exception] = 0 2365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # round in the new context 2367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(newcontext) 2368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # raise Inexact, and if necessary, Underflow 2370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep newcontext._raise_error(Inexact) 2371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if newcontext.flags[Subnormal]: 2372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep newcontext._raise_error(Underflow) 2373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # propagate signals to the original context; _fix could 2375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # have raised any of Overflow, Underflow, Subnormal, 2376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Inexact, Rounded, Clamped. Overflow needs the correct 2377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # arguments. Note that the order of the exceptions is 2378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # important here. 2379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if newcontext.flags[Overflow]: 2380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Overflow, 'above Emax', ans._sign) 2381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for exception in Underflow, Subnormal, Inexact, Rounded, Clamped: 2382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if newcontext.flags[exception]: 2383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(exception) 2384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(context) 2387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 2389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __rpow__(self, other, context=None): 2391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Swaps self/other and returns __pow__.""" 2392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other) 2393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other is NotImplemented: 2394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 2395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other.__pow__(self, context=context) 2396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def normalize(self, context=None): 2398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Normalize- strip trailing 0s, change anything equal to 0 to 0e0""" 2399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 2401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 2402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special: 2404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(context=context) 2405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 2406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 2407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dup = self._fix(context) 2409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if dup._isinfinity(): 2410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return dup 2411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not dup: 2413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(dup._sign, '0', 0) 2414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp_max = [context.Emax, context.Etop()][context._clamp] 2415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep end = len(dup._int) 2416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = dup._exp 2417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while dup._int[end-1] == '0' and exp < exp_max: 2418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp += 1 2419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep end -= 1 2420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(dup._sign, dup._int[:end], exp) 2421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def quantize(self, exp, rounding=None, context=None, watchexp=True): 2423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Quantize self so its exponent is the same as that of exp. 2424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Similar to self._rescale(exp._exp) but with error checking. 2426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 2427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = _convert_other(exp, raiseit=True) 2428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 2430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 2431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if rounding is None: 2432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rounding = context.rounding 2433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or exp._is_special: 2435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(exp, context) 2436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 2437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 2438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if exp._isinfinity() or self._isinfinity(): 2440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if exp._isinfinity() and self._isinfinity(): 2441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) # if both are inf, it is OK 2442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 2443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'quantize with one INF') 2444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # if we're not watching exponents, do a simple rescale 2446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not watchexp: 2447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._rescale(exp._exp, rounding) 2448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # raise Inexact and Rounded where appropriate 2449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans._exp > self._exp: 2450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Rounded) 2451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans != self: 2452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Inexact) 2453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 2454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exp._exp should be between Etiny and Emax 2456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not (context.Etiny() <= exp._exp <= context.Emax): 2457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 2458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'target exponent out of bounds in quantize') 2459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 2461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(self._sign, '0', exp._exp) 2462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans._fix(context) 2463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self_adjusted = self.adjusted() 2465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_adjusted > context.Emax: 2466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 2467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'exponent of quantize result too large for current context') 2468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_adjusted - exp._exp + 1 > context.prec: 2469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 2470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'quantize result has too many digits for current context') 2471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._rescale(exp._exp, rounding) 2473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans.adjusted() > context.Emax: 2474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 2475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'exponent of quantize result too large for current context') 2476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if len(ans._int) > context.prec: 2477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 2478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'quantize result has too many digits for current context') 2479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # raise appropriate flags 2481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans and ans.adjusted() < context.Emin: 2482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Subnormal) 2483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans._exp > self._exp: 2484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans != self: 2485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Inexact) 2486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Rounded) 2487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # call to fix takes care of any necessary folddown, and 2489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # signals Clamped if necessary 2490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(context) 2491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 2492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def same_quantum(self, other): 2494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if self and other have the same exponent; otherwise 2495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return False. 2496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If either operand is a special value, the following rules are used: 2498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep * return True if both operands are infinities 2499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep * return True if both operands are NaNs 2500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep * otherwise, return False. 2501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 2502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 2503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or other._is_special: 2504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return (self.is_nan() and other.is_nan() or 2505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.is_infinite() and other.is_infinite()) 2506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._exp == other._exp 2507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _rescale(self, exp, rounding): 2509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Rescale self so that the exponent is exp, either by padding with zeros 2510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep or by truncating digits, using the given rounding mode. 2511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Specials are returned without change. This operation is 2513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep quiet: it raises no flags, and uses no information from the 2514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context. 2515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = exp to scale to (an integer) 2517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rounding = rounding mode 2518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 2519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special: 2520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 2521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 2522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(self._sign, '0', exp) 2523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._exp >= exp: 2525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # pad answer with zeros if necessary 2526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(self._sign, 2527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._int + '0'*(self._exp - exp), exp) 2528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # too many digits; round and lose data. If self.adjusted() < 2530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exp-1, replace self by 10**(exp-1) before rounding 2531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep digits = len(self._int) + self._exp - exp 2532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if digits < 0: 2533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self = _dec_from_triple(self._sign, '1', exp-1) 2534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep digits = 0 2535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep this_function = self._pick_rounding_function[rounding] 2536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep changed = this_function(self, digits) 2537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff = self._int[:digits] or '0' 2538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if changed == 1: 2539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff = str(int(coeff)+1) 2540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(self._sign, coeff, exp) 2541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _round(self, places, rounding): 2543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Round a nonzero, nonspecial Decimal to a fixed number of 2544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep significant figures, using the given rounding mode. 2545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Infinities, NaNs and zeros are returned unaltered. 2547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This operation is quiet: it raises no flags, and uses no 2549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep information from the context. 2550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 2552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if places <= 0: 2553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError("argument should be at least 1 in _round") 2554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or not self: 2555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 2556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._rescale(self.adjusted()+1-places, rounding) 2557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # it can happen that the rescale alters the adjusted exponent; 2558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # for example when rounding 99.97 to 3 significant figures. 2559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # When this happens we end up with an extra 0 at the end of 2560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the number; a second rescale fixes this. 2561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans.adjusted() != self.adjusted(): 2562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._rescale(ans.adjusted()+1-places, rounding) 2563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 2564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def to_integral_exact(self, rounding=None, context=None): 2566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Rounds to a nearby integer. 2567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If no rounding mode is specified, take the rounding mode from 2569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the context. This method raises the Rounded and Inexact flags 2570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep when appropriate. 2571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep See also: to_integral_value, which does exactly the same as 2573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep this method except that it doesn't raise Inexact or Rounded. 2574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 2575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special: 2576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(context=context) 2577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 2578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 2579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 2580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._exp >= 0: 2581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 2582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 2583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(self._sign, '0', 0) 2584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 2585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 2586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if rounding is None: 2587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rounding = context.rounding 2588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._rescale(0, rounding) 2589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans != self: 2590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Inexact) 2591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Rounded) 2592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 2593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def to_integral_value(self, rounding=None, context=None): 2595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Rounds to the nearest integer, without raising inexact, rounded.""" 2596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 2597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 2598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if rounding is None: 2599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rounding = context.rounding 2600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special: 2601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(context=context) 2602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 2603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 2604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 2605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._exp >= 0: 2606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 2607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._rescale(0, rounding) 2609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the method name changed, but we provide also the old one, for compatibility 2611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep to_integral = to_integral_value 2612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def sqrt(self, context=None): 2614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return the square root of self.""" 2615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 2616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 2617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special: 2619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(context=context) 2620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 2621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 2622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity() and self._sign == 0: 2624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 2625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 2627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exponent = self._exp // 2. sqrt(-0) = -0 2628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(self._sign, '0', self._exp // 2) 2629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans._fix(context) 2630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign == 1: 2632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0') 2633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # At this point self represents a positive number. Let p be 2635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the desired precision and express self in the form c*100**e 2636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # with c a positive real number and e an integer, c and e 2637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # being chosen so that 100**(p-1) <= c < 100**p. Then the 2638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # (exact) square root of self is sqrt(c)*10**e, and 10**(p-1) 2639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # <= sqrt(c) < 10**p, so the closest representable Decimal at 2640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # precision p is n*10**e where n = round_half_even(sqrt(c)), 2641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the closest integer to sqrt(c) with the even integer chosen 2642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # in the case of a tie. 2643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 2644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # To ensure correct rounding in all cases, we use the 2645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # following trick: we compute the square root to an extra 2646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # place (precision p+1 instead of precision p), rounding down. 2647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Then, if the result is inexact and its last digit is 0 or 5, 2648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # we increase the last digit to 1 or 6 respectively; if it's 2649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exact we leave the last digit alone. Now the final round to 2650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # p places (or fewer in the case of underflow) will round 2651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # correctly and raise the appropriate flags. 2652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # use an extra digit of precision 2654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep prec = context.prec+1 2655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # write argument in the form c*100**e where e = self._exp//2 2657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # is the 'ideal' exponent, to be used if the square root is 2658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exactly representable. l is the number of 'digits' of c in 2659edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # base 100, so that 100**(l-1) <= c < 100**l. 2660edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op = _WorkRep(self) 2661edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep e = op.exp >> 1 2662edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if op.exp & 1: 2663edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = op.int * 10 2664edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep l = (len(self._int) >> 1) + 1 2665edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2666edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = op.int 2667edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep l = len(self._int)+1 >> 1 2668edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2669edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # rescale so that c has exactly prec base 100 'digits' 2670edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep shift = prec-l 2671edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if shift >= 0: 2672edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c *= 100**shift 2673edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exact = True 2674edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2675edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c, remainder = divmod(c, 100**-shift) 2676edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exact = not remainder 2677edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep e -= shift 2678edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2679edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # find n = floor(sqrt(c)) using Newton's method 2680edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep n = 10**prec 2681edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while True: 2682edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep q = c//n 2683edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if n <= q: 2684edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep break 2685edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2686edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep n = n + q >> 1 2687edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exact = exact and n*n == c 2688edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2689edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if exact: 2690edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # result is exact; rescale to use ideal exponent e 2691edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if shift >= 0: 2692edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # assert n % 10**shift == 0 2693edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep n //= 10**shift 2694edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2695edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep n *= 10**-shift 2696edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep e += shift 2697edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2698edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # result is not exact; fix last digit as described above 2699edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if n % 5 == 0: 2700edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep n += 1 2701edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2702edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(0, str(n), e) 2703edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2704edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # round, and fit to current context 2705edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = context._shallow_copy() 2706edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rounding = context._set_rounding(ROUND_HALF_EVEN) 2707edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(context) 2708edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context.rounding = rounding 2709edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2710edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 2711edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2712edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def max(self, other, context=None): 2713edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the larger value. 2714edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2715edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Like max(self, other) except if one is not a number, returns 2716edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep NaN (and signals if one is sNaN). Also rounds. 2717edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 2718edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 2719edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2720edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 2721edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 2722edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2723edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or other._is_special: 2724edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # If one operand is a quiet NaN and the other is number, then the 2725edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # number is always returned 2726edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sn = self._isnan() 2727edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep on = other._isnan() 2728edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sn or on: 2729edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if on == 1 and sn == 0: 2730edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._fix(context) 2731edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sn == 1 and on == 0: 2732edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other._fix(context) 2733edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._check_nans(other, context) 2734edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2735edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = self._cmp(other) 2736edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if c == 0: 2737edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # If both operands are finite and equal in numerical value 2738edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # then an ordering is applied: 2739edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 2740edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # If the signs differ then max returns the operand with the 2741edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # positive sign and min returns the operand with the negative sign 2742edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 2743edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # If the signs are the same then the exponent is used to select 2744edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the result. This is exactly the ordering used in compare_total. 2745edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = self.compare_total(other) 2746edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2747edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if c == -1: 2748edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = other 2749edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2750edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self 2751edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2752edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans._fix(context) 2753edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2754edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def min(self, other, context=None): 2755edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the smaller value. 2756edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2757edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Like min(self, other) except if one is not a number, returns 2758edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep NaN (and signals if one is sNaN). Also rounds. 2759edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 2760edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 2761edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2762edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 2763edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 2764edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2765edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or other._is_special: 2766edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # If one operand is a quiet NaN and the other is number, then the 2767edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # number is always returned 2768edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sn = self._isnan() 2769edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep on = other._isnan() 2770edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sn or on: 2771edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if on == 1 and sn == 0: 2772edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._fix(context) 2773edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sn == 1 and on == 0: 2774edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other._fix(context) 2775edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._check_nans(other, context) 2776edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2777edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = self._cmp(other) 2778edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if c == 0: 2779edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = self.compare_total(other) 2780edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2781edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if c == -1: 2782edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self 2783edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2784edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = other 2785edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2786edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans._fix(context) 2787edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2788edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _isinteger(self): 2789edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns whether self is an integer""" 2790edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special: 2791edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return False 2792edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._exp >= 0: 2793edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return True 2794edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rest = self._int[self._exp:] 2795edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return rest == '0'*len(rest) 2796edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2797edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _iseven(self): 2798edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns True if self is even. Assumes self is an integer.""" 2799edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self or self._exp > 0: 2800edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return True 2801edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._int[-1+self._exp] in '02468' 2802edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2803edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def adjusted(self): 2804edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return the adjusted exponent of self""" 2805edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 2806edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._exp + len(self._int) - 1 2807edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # If NaN or Infinity, self._exp is string 2808edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep except TypeError: 2809edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 0 2810edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2811edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def canonical(self, context=None): 2812edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the same Decimal object. 2813edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2814edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep As we do not have different encodings for the same number, the 2815edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep received object already is in its canonical form. 2816edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 2817edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self 2818edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2819edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def compare_signal(self, other, context=None): 2820edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compares self to the other operand numerically. 2821edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2822edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep It's pretty much like compare(), but all NaNs signal, with signaling 2823edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep NaNs taking precedence over quiet NaNs. 2824edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 2825edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit = True) 2826edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._compare_check_nans(other, context) 2827edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 2828edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 2829edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self.compare(other, context=context) 2830edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2831edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def compare_total(self, other): 2832edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compares self to other using the abstract representations. 2833edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2834edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This is not like the standard compare, which use their numerical 2835edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep value. Note that a total ordering is defined for all possible abstract 2836edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep representations. 2837edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 2838edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 2839edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2840edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # if one is negative and the other is positive, it's easy 2841edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign and not other._sign: 2842edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NegativeOne 2843edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self._sign and other._sign: 2844edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _One 2845edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = self._sign 2846edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2847edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # let's handle both NaN types 2848edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self_nan = self._isnan() 2849edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other_nan = other._isnan() 2850edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_nan or other_nan: 2851edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_nan == other_nan: 2852edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compare payloads as though they're integers 2853edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self_key = len(self._int), self._int 2854edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other_key = len(other._int), other._int 2855edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_key < other_key: 2856edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sign: 2857edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _One 2858edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2859edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NegativeOne 2860edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_key > other_key: 2861edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sign: 2862edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NegativeOne 2863edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2864edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _One 2865edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _Zero 2866edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2867edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sign: 2868edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_nan == 1: 2869edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NegativeOne 2870edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other_nan == 1: 2871edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _One 2872edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_nan == 2: 2873edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NegativeOne 2874edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other_nan == 2: 2875edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _One 2876edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2877edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_nan == 1: 2878edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _One 2879edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other_nan == 1: 2880edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NegativeOne 2881edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self_nan == 2: 2882edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _One 2883edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other_nan == 2: 2884edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NegativeOne 2885edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2886edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self < other: 2887edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NegativeOne 2888edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self > other: 2889edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _One 2890edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2891edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._exp < other._exp: 2892edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sign: 2893edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _One 2894edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2895edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NegativeOne 2896edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._exp > other._exp: 2897edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sign: 2898edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NegativeOne 2899edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2900edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _One 2901edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _Zero 2902edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2903edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2904edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def compare_total_mag(self, other): 2905edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compares self to other using abstract repr., ignoring sign. 2906edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2907edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Like compare_total, but with operand's sign ignored and assumed to be 0. 2908edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 2909edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 2910edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2911edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = self.copy_abs() 2912edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep o = other.copy_abs() 2913edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return s.compare_total(o) 2914edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2915edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def copy_abs(self): 2916edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns a copy with the sign set to 0. """ 2917edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(0, self._int, self._exp, self._is_special) 2918edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2919edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def copy_negate(self): 2920edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns a copy with the sign inverted.""" 2921edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign: 2922edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(0, self._int, self._exp, self._is_special) 2923edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2924edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(1, self._int, self._exp, self._is_special) 2925edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2926edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def copy_sign(self, other): 2927edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns self with the sign of other.""" 2928edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 2929edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(other._sign, self._int, 2930edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._exp, self._is_special) 2931edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2932edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def exp(self, context=None): 2933edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns e ** self.""" 2934edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2935edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 2936edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 2937edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2938edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exp(NaN) = NaN 2939edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(context=context) 2940edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 2941edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 2942edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2943edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exp(-Infinity) = 0 2944edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity() == -1: 2945edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _Zero 2946edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2947edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exp(0) = 1 2948edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 2949edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _One 2950edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2951edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exp(Infinity) = Infinity 2952edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity() == 1: 2953edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 2954edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2955edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the result is now guaranteed to be inexact (the true 2956edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # mathematical result is transcendental). There's no need to 2957edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # raise Rounded and Inexact here---they'll always be raised as 2958edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # a result of the call to _fix. 2959edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep p = context.prec 2960edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep adj = self.adjusted() 2961edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2962edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # we only need to do any computation for quite a small range 2963edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # of adjusted exponents---for example, -29 <= adj <= 10 for 2964edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the default context. For smaller exponent the result is 2965edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # indistinguishable from 1 at the given precision, while for 2966edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # larger exponent the result either overflows or underflows. 2967edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign == 0 and adj > len(str((context.Emax+1)*3)): 2968edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # overflow 2969edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(0, '1', context.Emax+1) 2970edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif self._sign == 1 and adj > len(str((-context.Etiny()+1)*3)): 2971edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # underflow to 0 2972edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(0, '1', context.Etiny()-1) 2973edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif self._sign == 0 and adj < -p: 2974edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # p+1 digits; final round will raise correct flags 2975edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(0, '1' + '0'*(p-1) + '1', -p) 2976edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif self._sign == 1 and adj < -p-1: 2977edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # p+1 digits; final round will raise correct flags 2978edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(0, '9'*(p+1), -p-1) 2979edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # general case 2980edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 2981edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op = _WorkRep(self) 2982edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c, e = op.int, op.exp 2983edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if op.sign == 1: 2984edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = -c 2985edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2986edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute correctly rounded result: increase precision by 2987edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 3 digits at a time until we get an unambiguously 2988edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # roundable result 2989edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep extra = 3 2990edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while True: 2991edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff, exp = _dexp(c, e, p+extra) 2992edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if coeff % (5*10**(len(str(coeff))-p-1)): 2993edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep break 2994edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep extra += 3 2995edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2996edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(0, str(coeff), exp) 2997edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2998edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # at this stage, ans should round correctly with *any* 2999edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # rounding mode, not just with ROUND_HALF_EVEN 3000edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = context._shallow_copy() 3001edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rounding = context._set_rounding(ROUND_HALF_EVEN) 3002edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(context) 3003edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context.rounding = rounding 3004edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3005edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 3006edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3007edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_canonical(self): 3008edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if self is canonical; otherwise return False. 3009edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3010edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Currently, the encoding of a Decimal instance is always 3011edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep canonical, so this method returns True for any Decimal. 3012edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3013edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return True 3014edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3015edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_finite(self): 3016edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if self is finite; otherwise return False. 3017edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3018edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep A Decimal instance is considered finite if it is neither 3019edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep infinite nor a NaN. 3020edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3021edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return not self._is_special 3022edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3023edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_infinite(self): 3024edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if self is infinite; otherwise return False.""" 3025edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._exp == 'F' 3026edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3027edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_nan(self): 3028edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if self is a qNaN or sNaN; otherwise return False.""" 3029edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._exp in ('n', 'N') 3030edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3031edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_normal(self, context=None): 3032edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if self is a normal number; otherwise return False.""" 3033edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or not self: 3034edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return False 3035edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3036edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3037edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context.Emin <= self.adjusted() 3038edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3039edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_qnan(self): 3040edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if self is a quiet NaN; otherwise return False.""" 3041edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._exp == 'n' 3042edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3043edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_signed(self): 3044edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if self is negative; otherwise return False.""" 3045edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._sign == 1 3046edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3047edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_snan(self): 3048edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if self is a signaling NaN; otherwise return False.""" 3049edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._exp == 'N' 3050edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3051edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_subnormal(self, context=None): 3052edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if self is subnormal; otherwise return False.""" 3053edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or not self: 3054edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return False 3055edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3056edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3057edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self.adjusted() < context.Emin 3058edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3059edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_zero(self): 3060edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if self is a zero; otherwise return False.""" 3061edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return not self._is_special and self._int == '0' 3062edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3063edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _ln_exp_bound(self): 3064edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compute a lower bound for the adjusted exponent of self.ln(). 3065edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep In other words, compute r such that self.ln() >= 10**r. Assumes 3066edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep that self is finite and positive and that self != 1. 3067edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3068edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3069edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # for 0.1 <= x <= 10 we use the inequalities 1-1/x <= ln(x) <= x-1 3070edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep adj = self._exp + len(self._int) - 1 3071edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if adj >= 1: 3072edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # argument >= 10; we use 23/10 = 2.3 as a lower bound for ln(10) 3073edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return len(str(adj*23//10)) - 1 3074edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if adj <= -2: 3075edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # argument <= 0.1 3076edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return len(str((-1-adj)*23//10)) - 1 3077edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op = _WorkRep(self) 3078edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c, e = op.int, op.exp 3079edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if adj == 0: 3080edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 1 < self < 10 3081edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep num = str(c-10**-e) 3082edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep den = str(c) 3083edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return len(num) - len(den) - (num < den) 3084edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # adj == -1, 0.1 <= self < 1 3085edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return e + len(str(10**-e - c)) - 1 3086edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3087edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3088edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def ln(self, context=None): 3089edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the natural (base e) logarithm of self.""" 3090edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3091edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3092edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3093edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3094edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # ln(NaN) = NaN 3095edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(context=context) 3096edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 3097edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 3098edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3099edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # ln(0.0) == -Infinity 3100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 3101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NegativeInfinity 3102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # ln(Infinity) = Infinity 3104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity() == 1: 3105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _Infinity 3106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # ln(1.0) == 0.0 3108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self == _One: 3109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _Zero 3110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # ln(negative) raises InvalidOperation 3112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign == 1: 3113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 3114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'ln of a negative value') 3115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # result is irrational, so necessarily inexact 3117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op = _WorkRep(self) 3118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c, e = op.int, op.exp 3119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep p = context.prec 3120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # correctly rounded result: repeatedly increase precision by 3 3122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # until we get an unambiguously roundable result 3123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep places = p - self._ln_exp_bound() + 2 # at least p+3 places 3124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while True: 3125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff = _dlog(c, e, places) 3126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # assert len(str(abs(coeff)))-p >= 1 3127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if coeff % (5*10**(len(str(abs(coeff)))-p-1)): 3128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep break 3129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep places += 3 3130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) 3131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = context._shallow_copy() 3133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rounding = context._set_rounding(ROUND_HALF_EVEN) 3134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(context) 3135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context.rounding = rounding 3136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 3137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _log10_exp_bound(self): 3139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compute a lower bound for the adjusted exponent of self.log10(). 3140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep In other words, find r such that self.log10() >= 10**r. 3141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Assumes that self is finite and positive and that self != 1. 3142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # For x >= 10 or x < 0.1 we only need a bound on the integer 3145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # part of log10(self), and this comes directly from the 3146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exponent of x. For 0.1 <= x <= 10 we use the inequalities 3147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 1-1/x <= log(x) <= x-1. If x > 1 we have |log10(x)| > 3148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # (1-1/x)/2.31 > 0. If x < 1 then |log10(x)| > (1-x)/2.31 > 0 3149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep adj = self._exp + len(self._int) - 1 3151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if adj >= 1: 3152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # self >= 10 3153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return len(str(adj))-1 3154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if adj <= -2: 3155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # self < 0.1 3156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return len(str(-1-adj))-1 3157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op = _WorkRep(self) 3158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c, e = op.int, op.exp 3159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if adj == 0: 3160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 1 < self < 10 3161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep num = str(c-10**-e) 3162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep den = str(231*c) 3163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return len(num) - len(den) - (num < den) + 2 3164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # adj == -1, 0.1 <= self < 1 3165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep num = str(10**-e-c) 3166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return len(num) + e - (num < "231") - 1 3167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def log10(self, context=None): 3169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the base 10 logarithm of self.""" 3170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # log10(NaN) = NaN 3175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(context=context) 3176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 3177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 3178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # log10(0.0) == -Infinity 3180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 3181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NegativeInfinity 3182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # log10(Infinity) = Infinity 3184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity() == 1: 3185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _Infinity 3186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # log10(negative or -Infinity) raises InvalidOperation 3188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign == 1: 3189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation, 3190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'log10 of a negative value') 3191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # log10(10**n) = n 3193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._int[0] == '1' and self._int[1:] == '0'*(len(self._int) - 1): 3194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # answer may need rounding 3195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = Decimal(self._exp + len(self._int) - 1) 3196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 3197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # result is irrational, so necessarily inexact 3198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep op = _WorkRep(self) 3199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c, e = op.int, op.exp 3200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep p = context.prec 3201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # correctly rounded result: repeatedly increase precision 3203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # until result is unambiguously roundable 3204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep places = p-self._log10_exp_bound()+2 3205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while True: 3206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff = _dlog10(c, e, places) 3207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # assert len(str(abs(coeff)))-p >= 1 3208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if coeff % (5*10**(len(str(abs(coeff)))-p-1)): 3209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep break 3210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep places += 3 3211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) 3212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = context._shallow_copy() 3214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rounding = context._set_rounding(ROUND_HALF_EVEN) 3215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = ans._fix(context) 3216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context.rounding = rounding 3217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 3218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def logb(self, context=None): 3220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ Returns the exponent of the magnitude of self's MSD. 3221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The result is the integer which is the exponent of the magnitude 3223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep of the most significant digit of self (as though it were truncated 3224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep to a single digit while maintaining the value of that digit and 3225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep without limiting the resulting exponent). 3226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # logb(NaN) = NaN 3228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(context=context) 3229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 3230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 3231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # logb(+/-Inf) = +Inf 3236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity(): 3237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _Infinity 3238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # logb(0) = -Inf, DivisionByZero 3240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self: 3241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(DivisionByZero, 'logb(0)', 1) 3242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # otherwise, simply return the adjusted exponent of self, as a 3244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Decimal. Note that no attempt is made to fit the result 3245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # into the current context. 3246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = Decimal(self.adjusted()) 3247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans._fix(context) 3248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _islogical(self): 3250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if self is a logical operand. 3251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep For being logical, it must be a finite number with a sign of 0, 3253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep an exponent of 0, and a coefficient whose digits must all be 3254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep either 0 or 1. 3255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign != 0 or self._exp != 0: 3257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return False 3258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for dig in self._int: 3259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if dig not in '01': 3260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return False 3261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return True 3262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _fill_logical(self, context, opa, opb): 3264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dif = context.prec - len(opa) 3265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if dif > 0: 3266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep opa = '0'*dif + opa 3267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif dif < 0: 3268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep opa = opa[-context.prec:] 3269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dif = context.prec - len(opb) 3270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if dif > 0: 3271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep opb = '0'*dif + opb 3272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif dif < 0: 3273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep opb = opb[-context.prec:] 3274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return opa, opb 3275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def logical_and(self, other, context=None): 3277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Applies an 'and' operation between self and other's digits.""" 3278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 3282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self._islogical() or not other._islogical(): 3284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation) 3285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # fill to context.prec 3287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (opa, opb) = self._fill_logical(context, self._int, other._int) 3288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # make the operation, and clean starting zeroes 3290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result = "".join([str(int(a)&int(b)) for a,b in zip(opa,opb)]) 3291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(0, result.lstrip('0') or '0', 0) 3292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def logical_invert(self, context=None): 3294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Invert all its digits.""" 3295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self.logical_xor(_dec_from_triple(0,'1'*context.prec,0), 3298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context) 3299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def logical_or(self, other, context=None): 3301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Applies an 'or' operation between self and other's digits.""" 3302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 3306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self._islogical() or not other._islogical(): 3308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation) 3309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # fill to context.prec 3311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (opa, opb) = self._fill_logical(context, self._int, other._int) 3312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # make the operation, and clean starting zeroes 3314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result = "".join([str(int(a)|int(b)) for a,b in zip(opa,opb)]) 3315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(0, result.lstrip('0') or '0', 0) 3316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def logical_xor(self, other, context=None): 3318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Applies an 'xor' operation between self and other's digits.""" 3319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 3323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self._islogical() or not other._islogical(): 3325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation) 3326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # fill to context.prec 3328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (opa, opb) = self._fill_logical(context, self._int, other._int) 3329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # make the operation, and clean starting zeroes 3331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result = "".join([str(int(a)^int(b)) for a,b in zip(opa,opb)]) 3332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(0, result.lstrip('0') or '0', 0) 3333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def max_mag(self, other, context=None): 3335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compares the values numerically with their sign ignored.""" 3336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 3337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or other._is_special: 3342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # If one operand is a quiet NaN and the other is number, then the 3343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # number is always returned 3344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sn = self._isnan() 3345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep on = other._isnan() 3346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sn or on: 3347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if on == 1 and sn == 0: 3348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._fix(context) 3349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sn == 1 and on == 0: 3350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other._fix(context) 3351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._check_nans(other, context) 3352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = self.copy_abs()._cmp(other.copy_abs()) 3354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if c == 0: 3355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = self.compare_total(other) 3356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if c == -1: 3358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = other 3359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 3360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self 3361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans._fix(context) 3363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def min_mag(self, other, context=None): 3365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compares the values numerically with their sign ignored.""" 3366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 3367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special or other._is_special: 3372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # If one operand is a quiet NaN and the other is number, then the 3373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # number is always returned 3374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sn = self._isnan() 3375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep on = other._isnan() 3376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sn or on: 3377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if on == 1 and sn == 0: 3378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._fix(context) 3379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sn == 1 and on == 0: 3380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other._fix(context) 3381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._check_nans(other, context) 3382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = self.copy_abs()._cmp(other.copy_abs()) 3384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if c == 0: 3385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = self.compare_total(other) 3386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if c == -1: 3388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self 3389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 3390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = other 3391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans._fix(context) 3393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def next_minus(self, context=None): 3395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the largest representable number smaller than itself.""" 3396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(context=context) 3400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 3401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 3402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity() == -1: 3404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _NegativeInfinity 3405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity() == 1: 3406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(0, '9'*context.prec, context.Etop()) 3407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = context.copy() 3409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._set_rounding(ROUND_FLOOR) 3410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._ignore_all_flags() 3411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep new_self = self._fix(context) 3412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if new_self != self: 3413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return new_self 3414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self.__sub__(_dec_from_triple(0, '1', context.Etiny()-1), 3415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context) 3416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def next_plus(self, context=None): 3418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the smallest representable number larger than itself.""" 3419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(context=context) 3423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 3424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 3425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity() == 1: 3427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _Infinity 3428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity() == -1: 3429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(1, '9'*context.prec, context.Etop()) 3430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = context.copy() 3432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._set_rounding(ROUND_CEILING) 3433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._ignore_all_flags() 3434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep new_self = self._fix(context) 3435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if new_self != self: 3436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return new_self 3437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self.__add__(_dec_from_triple(0, '1', context.Etiny()-1), 3438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context) 3439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def next_toward(self, other, context=None): 3441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the number closest to self, in the direction towards other. 3442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The result is the closest representable number to self 3444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (excluding self) that is in the direction towards other, 3445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless both have the same value. If the two operands are 3446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep numerically equal, then the result is a copy of self with the 3447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign set to be the same as the sign of other. 3448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 3450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(other, context) 3455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 3456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 3457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep comparison = self._cmp(other) 3459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if comparison == 0: 3460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self.copy_sign(other) 3461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if comparison == -1: 3463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self.next_plus(context) 3464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: # comparison == 1 3465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self.next_minus(context) 3466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # decide which flags to raise using value of ans 3468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans._isinfinity(): 3469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Overflow, 3470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'Infinite result from next_toward', 3471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans._sign) 3472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Inexact) 3473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Rounded) 3474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif ans.adjusted() < context.Emin: 3475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Underflow) 3476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Subnormal) 3477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Inexact) 3478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Rounded) 3479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # if precision == 1 then we don't raise Clamped for a 3480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # result 0E-Etiny. 3481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not ans: 3482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._raise_error(Clamped) 3483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 3485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def number_class(self, context=None): 3487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns an indication of the class of self. 3488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The class is one of the following strings: 3490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sNaN 3491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep NaN 3492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -Infinity 3493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -Normal 3494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -Subnormal 3495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -Zero 3496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep +Zero 3497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep +Subnormal 3498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep +Normal 3499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep +Infinity 3500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self.is_snan(): 3502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return "sNaN" 3503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self.is_qnan(): 3504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return "NaN" 3505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep inf = self._isinfinity() 3506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if inf == 1: 3507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return "+Infinity" 3508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if inf == -1: 3509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return "-Infinity" 3510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self.is_zero(): 3511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign: 3512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return "-Zero" 3513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 3514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return "+Zero" 3515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self.is_subnormal(context=context): 3518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign: 3519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return "-Subnormal" 3520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 3521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return "+Subnormal" 3522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # just a normal, regular, boring number, :) 3523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._sign: 3524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return "-Normal" 3525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 3526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return "+Normal" 3527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def radix(self): 3529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Just returns 10, as this is Decimal, :)""" 3530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(10) 3531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def rotate(self, other, context=None): 3533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns a rotated copy of self, value-of-other times.""" 3534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 3538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(other, context) 3540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 3541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 3542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._exp != 0: 3544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation) 3545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not (-context.prec <= int(other) <= context.prec): 3546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation) 3547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity(): 3549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 3550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # get values, pad if necessary 3552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep torot = int(other) 3553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rotdig = self._int 3554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep topad = context.prec - len(rotdig) 3555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if topad > 0: 3556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rotdig = '0'*topad + rotdig 3557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif topad < 0: 3558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rotdig = rotdig[-topad:] 3559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # let's rotate! 3561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rotated = rotdig[torot:] + rotdig[:torot] 3562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(self._sign, 3563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rotated.lstrip('0') or '0', self._exp) 3564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def scaleb(self, other, context=None): 3566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns self operand after adding the second value to its exp.""" 3567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 3571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(other, context) 3573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 3574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 3575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._exp != 0: 3577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation) 3578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep liminf = -2 * (context.Emax + context.prec) 3579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep limsup = 2 * (context.Emax + context.prec) 3580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not (liminf <= int(other) <= limsup): 3581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation) 3582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity(): 3584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 3585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep d = _dec_from_triple(self._sign, self._int, self._exp + int(other)) 3587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep d = d._fix(context) 3588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return d 3589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def shift(self, other, context=None): 3591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns a shifted copy of self, value-of-other times.""" 3592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = _convert_other(other, raiseit=True) 3596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ans = self._check_nans(other, context) 3598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ans: 3599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ans 3600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other._exp != 0: 3602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation) 3603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not (-context.prec <= int(other) <= context.prec): 3604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return context._raise_error(InvalidOperation) 3605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._isinfinity(): 3607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(self) 3608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # get values, pad if necessary 3610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep torot = int(other) 3611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rotdig = self._int 3612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep topad = context.prec - len(rotdig) 3613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if topad > 0: 3614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rotdig = '0'*topad + rotdig 3615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif topad < 0: 3616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rotdig = rotdig[-topad:] 3617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # let's shift! 3619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if torot < 0: 3620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep shifted = rotdig[:torot] 3621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 3622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep shifted = rotdig + '0'*torot 3623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep shifted = shifted[-context.prec:] 3624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _dec_from_triple(self._sign, 3626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep shifted.lstrip('0') or '0', self._exp) 3627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Support for pickling, copy, and deepcopy 3629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __reduce__(self): 3630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return (self.__class__, (str(self),)) 3631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __copy__(self): 3633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if type(self) is Decimal: 3634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self # I'm immutable; therefore I am my own clone 3635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self.__class__(str(self)) 3636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __deepcopy__(self, memo): 3638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if type(self) is Decimal: 3639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self # My components are also immutable 3640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self.__class__(str(self)) 3641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # PEP 3101 support. the _localeconv keyword argument should be 3643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # considered private: it's provided for ease of testing only. 3644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __format__(self, specifier, context=None, _localeconv=None): 3645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Format a Decimal instance according to the given specifier. 3646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The specifier should be a standard format specifier, with the 3648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep form described in PEP 3101. Formatting types 'e', 'E', 'f', 3649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'F', 'g', 'G', 'n' and '%' are supported. If the formatting 3650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep type is omitted it defaults to 'g' or 'G', depending on the 3651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep value of context.capitals. 3652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Note: PEP 3101 says that if the type is not present then 3655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # there should be at least one digit after the decimal point. 3656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # We take the liberty of ignoring this requirement for 3657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Decimal---it's presumably there to make sure that 3658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # format(float, '') behaves similarly to str(float). 3659edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if context is None: 3660edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = getcontext() 3661edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3662edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep spec = _parse_format_specifier(specifier, _localeconv=_localeconv) 3663edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3664edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # special values don't care about the type or precision 3665edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._is_special: 3666edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = _format_sign(self._sign, spec) 3667edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep body = str(self.copy_abs()) 3668edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _format_align(sign, body, spec) 3669edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3670edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # a type of None defaults to 'g' or 'G', depending on context 3671edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if spec['type'] is None: 3672edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep spec['type'] = ['g', 'G'][context.capitals] 3673edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3674edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # if type is '%', adjust exponent of self accordingly 3675edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if spec['type'] == '%': 3676edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self = _dec_from_triple(self._sign, self._int, self._exp+2) 3677edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3678edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # round if necessary, taking rounding mode from the context 3679edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rounding = context.rounding 3680edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep precision = spec['precision'] 3681edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if precision is not None: 3682edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if spec['type'] in 'eE': 3683edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self = self._round(precision+1, rounding) 3684edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif spec['type'] in 'fF%': 3685edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self = self._rescale(-precision, rounding) 3686edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif spec['type'] in 'gG' and len(self._int) > precision: 3687edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self = self._round(precision, rounding) 3688edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # special case: zeros with a positive exponent can't be 3689edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # represented in fixed point; rescale them to 0e0. 3690edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self and self._exp > 0 and spec['type'] in 'fF%': 3691edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self = self._rescale(0, rounding) 3692edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3693edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # figure out placement of the decimal point 3694edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep leftdigits = self._exp + len(self._int) 3695edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if spec['type'] in 'eE': 3696edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self and precision is not None: 3697edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dotplace = 1 - precision 3698edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 3699edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dotplace = 1 3700edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif spec['type'] in 'fF%': 3701edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dotplace = leftdigits 3702edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif spec['type'] in 'gG': 3703edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self._exp <= 0 and leftdigits > -6: 3704edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dotplace = leftdigits 3705edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 3706edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dotplace = 1 3707edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3708edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # find digits before and after decimal point, and get exponent 3709edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if dotplace < 0: 3710edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep intpart = '0' 3711edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fracpart = '0'*(-dotplace) + self._int 3712edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif dotplace > len(self._int): 3713edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep intpart = self._int + '0'*(dotplace-len(self._int)) 3714edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fracpart = '' 3715edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 3716edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep intpart = self._int[:dotplace] or '0' 3717edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fracpart = self._int[dotplace:] 3718edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = leftdigits-dotplace 3719edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3720edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # done with the decimal-specific stuff; hand over the rest 3721edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # of the formatting to the _format_number function 3722edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _format_number(self._sign, intpart, fracpart, exp, spec) 3723edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3724edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _dec_from_triple(sign, coefficient, exponent, special=False): 3725edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Create a decimal instance directly, without any validation, 3726edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep normalization (e.g. removal of leading zeros) or argument 3727edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep conversion. 3728edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3729edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This function is for *internal use only*. 3730edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3731edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3732edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self = object.__new__(Decimal) 3733edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._sign = sign 3734edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._int = coefficient 3735edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._exp = exponent 3736edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._is_special = special 3737edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3738edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self 3739edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3740edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Register Decimal as a kind of Number (an abstract base class). 3741edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# However, do not register it as Real (because Decimals are not 3742edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# interoperable with floats). 3743edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_numbers.Number.register(Decimal) 3744edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3745edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3746edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### Context class ####################################################### 3747edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3748edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass _ContextManager(object): 3749edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Context manager class to support localcontext(). 3750edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3751edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Sets a copy of the supplied context in __enter__() and restores 3752edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the previous decimal context in __exit__() 3753edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3754edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __init__(self, new_context): 3755edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.new_context = new_context.copy() 3756edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __enter__(self): 3757edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.saved_context = getcontext() 3758edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep setcontext(self.new_context) 3759edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self.new_context 3760edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __exit__(self, t, v, tb): 3761edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep setcontext(self.saved_context) 3762edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3763edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Context(object): 3764edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Contains the context for a Decimal instance. 3765edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3766edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Contains: 3767edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep prec - precision (for use in rounding, division, square roots..) 3768edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rounding - rounding type (how you round) 3769edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep traps - If traps[exception] = 1, then the exception is 3770edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raised when it is caused. Otherwise, a value is 3771edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep substituted in. 3772edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep flags - When an exception is caused, flags[exception] is set. 3773edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (Whether or not the trap_enabler is set) 3774edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Should be reset by user of Decimal instance. 3775edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Emin - Minimum exponent 3776edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Emax - Maximum exponent 3777edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep capitals - If 1, 1*10^1 is printed as 1E+1. 3778edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If 0, printed as 1e1 3779edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep _clamp - If 1, change exponents if too high (Default 0) 3780edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3781edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3782edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __init__(self, prec=None, rounding=None, 3783edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep traps=None, flags=None, 3784edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Emin=None, Emax=None, 3785edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep capitals=None, _clamp=0, 3786edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep _ignored_flags=None): 3787edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Set defaults; for everything except flags and _ignored_flags, 3788edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # inherit from DefaultContext. 3789edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 3790edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dc = DefaultContext 3791edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep except NameError: 3792edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep pass 3793edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3794edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.prec = prec if prec is not None else dc.prec 3795edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.rounding = rounding if rounding is not None else dc.rounding 3796edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.Emin = Emin if Emin is not None else dc.Emin 3797edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.Emax = Emax if Emax is not None else dc.Emax 3798edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.capitals = capitals if capitals is not None else dc.capitals 3799edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._clamp = _clamp if _clamp is not None else dc._clamp 3800edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3801edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if _ignored_flags is None: 3802edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._ignored_flags = [] 3803edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 3804edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._ignored_flags = _ignored_flags 3805edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3806edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if traps is None: 3807edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.traps = dc.traps.copy() 3808edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif not isinstance(traps, dict): 3809edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.traps = dict((s, int(s in traps)) for s in _signals) 3810edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 3811edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.traps = traps 3812edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3813edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if flags is None: 3814edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.flags = dict.fromkeys(_signals, 0) 3815edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif not isinstance(flags, dict): 3816edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.flags = dict((s, int(s in flags)) for s in _signals) 3817edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 3818edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.flags = flags 3819edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3820edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __repr__(self): 3821edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Show the current context.""" 3822edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = [] 3823edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s.append('Context(prec=%(prec)d, rounding=%(rounding)s, ' 3824edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' 3825edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep % vars(self)) 3826edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep names = [f.__name__ for f, v in self.flags.items() if v] 3827edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s.append('flags=[' + ', '.join(names) + ']') 3828edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep names = [t.__name__ for t, v in self.traps.items() if v] 3829edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s.append('traps=[' + ', '.join(names) + ']') 3830edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return ', '.join(s) + ')' 3831edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3832edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def clear_flags(self): 3833edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Reset all flags to zero""" 3834edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for flag in self.flags: 3835edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.flags[flag] = 0 3836edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3837edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _shallow_copy(self): 3838edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns a shallow copy from self.""" 3839edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep nc = Context(self.prec, self.rounding, self.traps, 3840edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.flags, self.Emin, self.Emax, 3841edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.capitals, self._clamp, self._ignored_flags) 3842edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return nc 3843edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3844edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def copy(self): 3845edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns a deep copy from self.""" 3846edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep nc = Context(self.prec, self.rounding, self.traps.copy(), 3847edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.flags.copy(), self.Emin, self.Emax, 3848edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.capitals, self._clamp, self._ignored_flags) 3849edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return nc 3850edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep __copy__ = copy 3851edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3852edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _raise_error(self, condition, explanation = None, *args): 3853edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Handles an error 3854edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3855edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If the flag is in _ignored_flags, returns the default response. 3856edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Otherwise, it sets the flag, then, if the corresponding 3857edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep trap_enabler is set, it reraises the exception. Otherwise, it returns 3858edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the default value after setting the flag. 3859edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3860edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep error = _condition_map.get(condition, condition) 3861edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if error in self._ignored_flags: 3862edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Don't touch the flag 3863edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return error().handle(self, *args) 3864edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3865edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.flags[error] = 1 3866edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not self.traps[error]: 3867edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # The errors define how to handle themselves. 3868edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return condition().handle(self, *args) 3869edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3870edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Errors should only be risked on copies of the context 3871edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # self._ignored_flags = [] 3872edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise error(explanation) 3873edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3874edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _ignore_all_flags(self): 3875edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Ignore all flags, if they are raised""" 3876edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._ignore_flags(*_signals) 3877edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3878edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _ignore_flags(self, *flags): 3879edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Ignore the flags, if they are raised""" 3880edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Do not mutate-- This way, copies of a context leave the original 3881edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # alone. 3882edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._ignored_flags = (self._ignored_flags + list(flags)) 3883edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return list(flags) 3884edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3885edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _regard_flags(self, *flags): 3886edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Stop ignoring the flags, if they are raised""" 3887edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if flags and isinstance(flags[0], (tuple,list)): 3888edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep flags = flags[0] 3889edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for flag in flags: 3890edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._ignored_flags.remove(flag) 3891edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3892edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # We inherit object.__hash__, so we must deny this explicitly 3893edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep __hash__ = None 3894edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3895edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def Etiny(self): 3896edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns Etiny (= Emin - prec + 1)""" 3897edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return int(self.Emin - self.prec + 1) 3898edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3899edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def Etop(self): 3900edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns maximum exponent (= Emax - prec + 1)""" 3901edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return int(self.Emax - self.prec + 1) 3902edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3903edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _set_rounding(self, type): 3904edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Sets the rounding type. 3905edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3906edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Sets the rounding type, and returns the current (previous) 3907edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rounding type. Often used like: 3908edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3909edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context = context.copy() 3910edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # so you don't change the calling context 3911edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # if an error occurs in the middle. 3912edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rounding = context._set_rounding(ROUND_UP) 3913edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep val = self.__sub__(other, context=context) 3914edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context._set_rounding(rounding) 3915edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3916edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This will make it round up for that operation. 3917edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3918edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rounding = self.rounding 3919edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.rounding= type 3920edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return rounding 3921edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3922edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def create_decimal(self, num='0'): 3923edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Creates a new Decimal instance but using self as context. 3924edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3925edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This method implements the to-number operation of the 3926edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep IBM Decimal specification.""" 3927edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3928edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if isinstance(num, basestring) and num != num.strip(): 3929edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._raise_error(ConversionSyntax, 3930edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "no trailing or leading whitespace is " 3931edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "permitted.") 3932edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3933edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep d = Decimal(num, context=self) 3934edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if d._isnan() and len(d._int) > self.prec - self._clamp: 3935edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._raise_error(ConversionSyntax, 3936edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "diagnostic info too long in NaN") 3937edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return d._fix(self) 3938edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3939edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def create_decimal_from_float(self, f): 3940edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Creates a new Decimal instance from a float but rounding using self 3941edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep as the context. 3942edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3943edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> context = Context(prec=5, rounding=ROUND_DOWN) 3944edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> context.create_decimal_from_float(3.1415926535897932) 3945edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3.1415') 3946edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> context = Context(prec=5, traps=[Inexact]) 3947edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> context.create_decimal_from_float(3.1415926535897932) 3948edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Traceback (most recent call last): 3949edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ... 3950edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Inexact: None 3951edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3952edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3953edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep d = Decimal.from_float(f) # An exact conversion 3954edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return d._fix(self) # Apply the context rounding 3955edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3956edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Methods 3957edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def abs(self, a): 3958edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the absolute value of the operand. 3959edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3960edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If the operand is negative, the result is the same as using the minus 3961edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep operation on the operand. Otherwise, the result is the same as using 3962edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the plus operation on the operand. 3963edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3964edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.abs(Decimal('2.1')) 3965edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.1') 3966edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.abs(Decimal('-100')) 3967edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('100') 3968edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.abs(Decimal('101.5')) 3969edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('101.5') 3970edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.abs(Decimal('-101.5')) 3971edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('101.5') 3972edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.abs(-1) 3973edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 3974edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3975edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 3976edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.__abs__(context=self) 3977edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3978edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def add(self, a, b): 3979edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return the sum of the two operands. 3980edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3981edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.add(Decimal('12'), Decimal('7.00')) 3982edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('19.00') 3983edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4')) 3984edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.02E+4') 3985edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.add(1, Decimal(2)) 3986edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3') 3987edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.add(Decimal(8), 5) 3988edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('13') 3989edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.add(5, 5) 3990edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('10') 3991edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 3992edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 3993edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r = a.__add__(b, context=self) 3994edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if r is NotImplemented: 3995edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise TypeError("Unable to convert %s to Decimal" % b) 3996edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 3997edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return r 3998edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3999edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _apply(self, a): 4000edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return str(a._fix(self)) 4001edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4002edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def canonical(self, a): 4003edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the same Decimal object. 4004edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4005edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep As we do not have different encodings for the same number, the 4006edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep received object already is in its canonical form. 4007edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4008edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.canonical(Decimal('2.50')) 4009edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.50') 4010edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4011edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.canonical(context=self) 4012edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4013edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def compare(self, a, b): 4014edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compares values numerically. 4015edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4016edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If the signs of the operands differ, a value representing each operand 4017edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('-1' if the operand is less than zero, '0' if the operand is zero or 4018edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep negative zero, or '1' if the operand is greater than zero) is used in 4019edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep place of that operand for the comparison instead of the actual 4020edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep operand. 4021edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4022edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The comparison is then effected by subtracting the second operand from 4023edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the first and then returning a value according to the result of the 4024edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subtraction: '-1' if the result is less than zero, '0' if the result is 4025edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep zero or negative zero, or '1' if the result is greater than zero. 4026edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4027edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3')) 4028edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4029edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1')) 4030edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4031edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10')) 4032edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4033edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1')) 4034edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4035edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3')) 4036edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4037edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1')) 4038edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4039edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare(1, 2) 4040edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4041edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare(Decimal(1), 2) 4042edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4043edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare(1, Decimal(2)) 4044edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4045edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4046edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4047edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.compare(b, context=self) 4048edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4049edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def compare_signal(self, a, b): 4050edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compares the values of the two operands numerically. 4051edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4052edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep It's pretty much like compare(), but all NaNs signal, with signaling 4053edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep NaNs taking precedence over quiet NaNs. 4054edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4055edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c = ExtendedContext 4056edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.compare_signal(Decimal('2.1'), Decimal('3')) 4057edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4058edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.compare_signal(Decimal('2.1'), Decimal('2.1')) 4059edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4060edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.flags[InvalidOperation] = 0 4061edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> print c.flags[InvalidOperation] 4062edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 0 4063edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.compare_signal(Decimal('NaN'), Decimal('2.1')) 4064edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('NaN') 4065edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> print c.flags[InvalidOperation] 4066edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1 4067edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.flags[InvalidOperation] = 0 4068edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> print c.flags[InvalidOperation] 4069edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 0 4070edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.compare_signal(Decimal('sNaN'), Decimal('2.1')) 4071edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('NaN') 4072edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> print c.flags[InvalidOperation] 4073edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1 4074edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.compare_signal(-1, 2) 4075edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4076edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.compare_signal(Decimal(-1), 2) 4077edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4078edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.compare_signal(-1, Decimal(2)) 4079edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4080edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4081edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4082edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.compare_signal(b, context=self) 4083edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4084edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def compare_total(self, a, b): 4085edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compares two operands using their abstract representation. 4086edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4087edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This is not like the standard compare, which use their numerical 4088edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep value. Note that a total ordering is defined for all possible abstract 4089edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep representations. 4090edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4091edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare_total(Decimal('12.73'), Decimal('127.9')) 4092edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4093edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare_total(Decimal('-127'), Decimal('12')) 4094edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4095edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.3')) 4096edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4097edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.30')) 4098edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4099edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare_total(Decimal('12.3'), Decimal('12.300')) 4100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare_total(Decimal('12.3'), Decimal('NaN')) 4102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare_total(1, 2) 4104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare_total(Decimal(1), 2) 4106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.compare_total(1, Decimal(2)) 4108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.compare_total(b) 4112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def compare_total_mag(self, a, b): 4114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compares two operands using their abstract representation ignoring sign. 4115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Like compare_total, but with operand's sign ignored and assumed to be 0. 4117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.compare_total_mag(b) 4120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def copy_abs(self, a): 4122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns a copy of the operand with the sign set to 0. 4123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_abs(Decimal('2.1')) 4125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.1') 4126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_abs(Decimal('-100')) 4127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('100') 4128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_abs(-1) 4129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.copy_abs() 4133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def copy_decimal(self, a): 4135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns a copy of the decimal object. 4136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_decimal(Decimal('2.1')) 4138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.1') 4139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_decimal(Decimal('-1.00')) 4140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1.00') 4141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_decimal(1) 4142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(a) 4146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def copy_negate(self, a): 4148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns a copy of the operand with the sign inverted. 4149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_negate(Decimal('101.5')) 4151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-101.5') 4152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_negate(Decimal('-101.5')) 4153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('101.5') 4154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_negate(1) 4155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.copy_negate() 4159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def copy_sign(self, a, b): 4161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Copies the second operand's sign to the first one. 4162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep In detail, it returns a copy of the first operand with the sign 4164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep equal to the sign of the second operand. 4165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('7.33')) 4167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.50') 4168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('7.33')) 4169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.50') 4170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('-7.33')) 4171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1.50') 4172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('-7.33')) 4173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1.50') 4174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_sign(1, -2) 4175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_sign(Decimal(1), -2) 4177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.copy_sign(1, Decimal(-2)) 4179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.copy_sign(b) 4183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def divide(self, a, b): 4185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Decimal division in a specified context. 4186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide(Decimal('1'), Decimal('3')) 4188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.333333333') 4189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide(Decimal('2'), Decimal('3')) 4190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.666666667') 4191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide(Decimal('5'), Decimal('2')) 4192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.5') 4193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide(Decimal('1'), Decimal('10')) 4194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.1') 4195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide(Decimal('12'), Decimal('12')) 4196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2')) 4198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('4.00') 4199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0')) 4200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.20') 4201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide(Decimal('1000'), Decimal('100')) 4202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('10') 4203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide(Decimal('1000'), Decimal('1')) 4204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1000') 4205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2')) 4206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.20E+6') 4207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide(5, 5) 4208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide(Decimal(5), 5) 4210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide(5, Decimal(5)) 4212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r = a.__div__(b, context=self) 4216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if r is NotImplemented: 4217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise TypeError("Unable to convert %s to Decimal" % b) 4218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 4219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return r 4220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def divide_int(self, a, b): 4222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Divides two numbers and returns the integer part of the result. 4223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3')) 4225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3')) 4227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3') 4228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3')) 4229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3') 4230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide_int(10, 3) 4231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3') 4232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide_int(Decimal(10), 3) 4233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3') 4234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divide_int(10, Decimal(3)) 4235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3') 4236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r = a.__floordiv__(b, context=self) 4239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if r is NotImplemented: 4240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise TypeError("Unable to convert %s to Decimal" % b) 4241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 4242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return r 4243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def divmod(self, a, b): 4245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return (a // b, a % b). 4246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divmod(Decimal(8), Decimal(3)) 4248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (Decimal('2'), Decimal('2')) 4249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divmod(Decimal(8), Decimal(4)) 4250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (Decimal('2'), Decimal('0')) 4251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divmod(8, 4) 4252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (Decimal('2'), Decimal('0')) 4253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divmod(Decimal(8), 4) 4254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (Decimal('2'), Decimal('0')) 4255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.divmod(8, Decimal(4)) 4256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (Decimal('2'), Decimal('0')) 4257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r = a.__divmod__(b, context=self) 4260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if r is NotImplemented: 4261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise TypeError("Unable to convert %s to Decimal" % b) 4262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 4263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return r 4264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def exp(self, a): 4266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns e ** a. 4267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c = ExtendedContext.copy() 4269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emin = -999 4270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emax = 999 4271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.exp(Decimal('-Infinity')) 4272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.exp(Decimal('-1')) 4274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.367879441') 4275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.exp(Decimal('0')) 4276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.exp(Decimal('1')) 4278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.71828183') 4279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.exp(Decimal('0.693147181')) 4280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.00000000') 4281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.exp(Decimal('+Infinity')) 4282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('Infinity') 4283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.exp(10) 4284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('22026.4658') 4285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a =_convert_other(a, raiseit=True) 4287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.exp(context=self) 4288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def fma(self, a, b, c): 4290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns a multiplied by b, plus c. 4291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The first two operands are multiplied together, using multiply, 4293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the third operand is then added to the result of that 4294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep multiplication, using add, all with only one final rounding. 4295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.fma(Decimal('3'), Decimal('5'), Decimal('7')) 4297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('22') 4298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.fma(Decimal('3'), Decimal('-5'), Decimal('7')) 4299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-8') 4300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.fma(Decimal('888565290'), Decimal('1557.96930'), Decimal('-86087.7578')) 4301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.38435736E+12') 4302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.fma(1, 3, 4) 4303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('7') 4304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.fma(1, Decimal(3), 4) 4305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('7') 4306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.fma(1, 3, Decimal(4)) 4307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('7') 4308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.fma(b, c, context=self) 4311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_canonical(self, a): 4313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if the operand is canonical; otherwise return False. 4314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Currently, the encoding of a Decimal instance is always 4316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep canonical, so this method returns True for any Decimal. 4317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_canonical(Decimal('2.50')) 4319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.is_canonical() 4322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_finite(self, a): 4324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if the operand is finite; otherwise return False. 4325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep A Decimal instance is considered finite if it is neither 4327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep infinite nor a NaN. 4328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_finite(Decimal('2.50')) 4330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_finite(Decimal('-0.3')) 4332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_finite(Decimal('0')) 4334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_finite(Decimal('Inf')) 4336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_finite(Decimal('NaN')) 4338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_finite(1) 4340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.is_finite() 4344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_infinite(self, a): 4346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if the operand is infinite; otherwise return False. 4347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_infinite(Decimal('2.50')) 4349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_infinite(Decimal('-Inf')) 4351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_infinite(Decimal('NaN')) 4353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_infinite(1) 4355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.is_infinite() 4359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_nan(self, a): 4361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if the operand is a qNaN or sNaN; 4362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep otherwise return False. 4363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_nan(Decimal('2.50')) 4365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_nan(Decimal('NaN')) 4367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_nan(Decimal('-sNaN')) 4369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_nan(1) 4371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.is_nan() 4375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_normal(self, a): 4377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if the operand is a normal number; 4378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep otherwise return False. 4379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c = ExtendedContext.copy() 4381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emin = -999 4382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emax = 999 4383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.is_normal(Decimal('2.50')) 4384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.is_normal(Decimal('0.1E-999')) 4386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.is_normal(Decimal('0.00')) 4388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.is_normal(Decimal('-Inf')) 4390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.is_normal(Decimal('NaN')) 4392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.is_normal(1) 4394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.is_normal(context=self) 4398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_qnan(self, a): 4400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if the operand is a quiet NaN; otherwise return False. 4401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_qnan(Decimal('2.50')) 4403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_qnan(Decimal('NaN')) 4405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_qnan(Decimal('sNaN')) 4407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_qnan(1) 4409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.is_qnan() 4413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_signed(self, a): 4415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if the operand is negative; otherwise return False. 4416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_signed(Decimal('2.50')) 4418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_signed(Decimal('-12')) 4420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_signed(Decimal('-0')) 4422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_signed(8) 4424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_signed(-8) 4426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.is_signed() 4430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_snan(self, a): 4432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if the operand is a signaling NaN; 4433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep otherwise return False. 4434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_snan(Decimal('2.50')) 4436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_snan(Decimal('NaN')) 4438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_snan(Decimal('sNaN')) 4440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_snan(1) 4442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.is_snan() 4446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_subnormal(self, a): 4448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if the operand is subnormal; otherwise return False. 4449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c = ExtendedContext.copy() 4451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emin = -999 4452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emax = 999 4453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.is_subnormal(Decimal('2.50')) 4454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.is_subnormal(Decimal('0.1E-999')) 4456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.is_subnormal(Decimal('0.00')) 4458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.is_subnormal(Decimal('-Inf')) 4460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.is_subnormal(Decimal('NaN')) 4462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.is_subnormal(1) 4464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.is_subnormal(context=self) 4468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def is_zero(self, a): 4470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return True if the operand is a zero; otherwise return False. 4471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_zero(Decimal('0')) 4473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_zero(Decimal('2.50')) 4475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_zero(Decimal('-0E+2')) 4477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_zero(1) 4479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 4480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.is_zero(0) 4481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 4482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.is_zero() 4485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def ln(self, a): 4487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the natural (base e) logarithm of the operand. 4488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c = ExtendedContext.copy() 4490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emin = -999 4491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emax = 999 4492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.ln(Decimal('0')) 4493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-Infinity') 4494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.ln(Decimal('1.000')) 4495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.ln(Decimal('2.71828183')) 4497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.00000000') 4498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.ln(Decimal('10')) 4499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.30258509') 4500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.ln(Decimal('+Infinity')) 4501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('Infinity') 4502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.ln(1) 4503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.ln(context=self) 4507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def log10(self, a): 4509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the base 10 logarithm of the operand. 4510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c = ExtendedContext.copy() 4512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emin = -999 4513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emax = 999 4514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.log10(Decimal('0')) 4515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-Infinity') 4516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.log10(Decimal('0.001')) 4517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-3') 4518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.log10(Decimal('1.000')) 4519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.log10(Decimal('2')) 4521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.301029996') 4522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.log10(Decimal('10')) 4523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.log10(Decimal('70')) 4525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.84509804') 4526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.log10(Decimal('+Infinity')) 4527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('Infinity') 4528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.log10(0) 4529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-Infinity') 4530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.log10(1) 4531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.log10(context=self) 4535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def logb(self, a): 4537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ Returns the exponent of the magnitude of the operand's MSD. 4538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The result is the integer which is the exponent of the magnitude 4540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep of the most significant digit of the operand (as though the 4541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep operand were truncated to a single digit while maintaining the 4542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep value of that digit and without limiting the resulting exponent). 4543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logb(Decimal('250')) 4545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2') 4546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logb(Decimal('2.50')) 4547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logb(Decimal('0.03')) 4549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-2') 4550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logb(Decimal('0')) 4551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-Infinity') 4552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logb(1) 4553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logb(10) 4555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logb(100) 4557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2') 4558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.logb(context=self) 4561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def logical_and(self, a, b): 4563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Applies the logical operation 'and' between each operand's digits. 4564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The operands must be both logical numbers. 4566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_and(Decimal('0'), Decimal('0')) 4568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_and(Decimal('0'), Decimal('1')) 4570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_and(Decimal('1'), Decimal('0')) 4572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_and(Decimal('1'), Decimal('1')) 4574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_and(Decimal('1100'), Decimal('1010')) 4576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1000') 4577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_and(Decimal('1111'), Decimal('10')) 4578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('10') 4579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_and(110, 1101) 4580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('100') 4581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_and(Decimal(110), 1101) 4582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('100') 4583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_and(110, Decimal(1101)) 4584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('100') 4585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.logical_and(b, context=self) 4588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def logical_invert(self, a): 4590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Invert all the digits in the operand. 4591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The operand must be a logical number. 4593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_invert(Decimal('0')) 4595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('111111111') 4596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_invert(Decimal('1')) 4597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('111111110') 4598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_invert(Decimal('111111111')) 4599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_invert(Decimal('101010101')) 4601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('10101010') 4602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_invert(1101) 4603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('111110010') 4604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.logical_invert(context=self) 4607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def logical_or(self, a, b): 4609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Applies the logical operation 'or' between each operand's digits. 4610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The operands must be both logical numbers. 4612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_or(Decimal('0'), Decimal('0')) 4614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_or(Decimal('0'), Decimal('1')) 4616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_or(Decimal('1'), Decimal('0')) 4618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_or(Decimal('1'), Decimal('1')) 4620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_or(Decimal('1100'), Decimal('1010')) 4622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1110') 4623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_or(Decimal('1110'), Decimal('10')) 4624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1110') 4625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_or(110, 1101) 4626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1111') 4627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_or(Decimal(110), 1101) 4628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1111') 4629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_or(110, Decimal(1101)) 4630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1111') 4631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.logical_or(b, context=self) 4634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def logical_xor(self, a, b): 4636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Applies the logical operation 'xor' between each operand's digits. 4637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The operands must be both logical numbers. 4639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('0')) 4641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('1')) 4643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('0')) 4645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('1')) 4647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_xor(Decimal('1100'), Decimal('1010')) 4649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('110') 4650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_xor(Decimal('1111'), Decimal('10')) 4651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1101') 4652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_xor(110, 1101) 4653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1011') 4654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_xor(Decimal(110), 1101) 4655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1011') 4656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.logical_xor(110, Decimal(1101)) 4657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1011') 4658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4659edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4660edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.logical_xor(b, context=self) 4661edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4662edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def max(self, a, b): 4663edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """max compares two values numerically and returns the maximum. 4664edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4665edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If either operand is a NaN then the general rules apply. 4666edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Otherwise, the operands are compared as though by the compare 4667edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep operation. If they are numerically equal then the left-hand operand 4668edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep is chosen as the result. Otherwise the maximum (closer to positive 4669edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep infinity) of the two operands is chosen as the result. 4670edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4671edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.max(Decimal('3'), Decimal('2')) 4672edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3') 4673edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.max(Decimal('-10'), Decimal('3')) 4674edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3') 4675edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.max(Decimal('1.0'), Decimal('1')) 4676edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4677edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.max(Decimal('7'), Decimal('NaN')) 4678edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('7') 4679edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.max(1, 2) 4680edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2') 4681edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.max(Decimal(1), 2) 4682edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2') 4683edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.max(1, Decimal(2)) 4684edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2') 4685edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4686edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4687edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.max(b, context=self) 4688edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4689edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def max_mag(self, a, b): 4690edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compares the values numerically with their sign ignored. 4691edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4692edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.max_mag(Decimal('7'), Decimal('NaN')) 4693edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('7') 4694edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.max_mag(Decimal('7'), Decimal('-10')) 4695edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-10') 4696edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.max_mag(1, -2) 4697edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-2') 4698edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.max_mag(Decimal(1), -2) 4699edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-2') 4700edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.max_mag(1, Decimal(-2)) 4701edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-2') 4702edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4703edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4704edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.max_mag(b, context=self) 4705edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4706edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def min(self, a, b): 4707edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """min compares two values numerically and returns the minimum. 4708edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4709edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If either operand is a NaN then the general rules apply. 4710edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Otherwise, the operands are compared as though by the compare 4711edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep operation. If they are numerically equal then the left-hand operand 4712edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep is chosen as the result. Otherwise the minimum (closer to negative 4713edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep infinity) of the two operands is chosen as the result. 4714edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4715edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.min(Decimal('3'), Decimal('2')) 4716edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2') 4717edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.min(Decimal('-10'), Decimal('3')) 4718edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-10') 4719edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.min(Decimal('1.0'), Decimal('1')) 4720edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.0') 4721edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.min(Decimal('7'), Decimal('NaN')) 4722edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('7') 4723edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.min(1, 2) 4724edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4725edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.min(Decimal(1), 2) 4726edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4727edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.min(1, Decimal(29)) 4728edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4729edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4730edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4731edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.min(b, context=self) 4732edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4733edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def min_mag(self, a, b): 4734edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compares the values numerically with their sign ignored. 4735edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4736edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.min_mag(Decimal('3'), Decimal('-2')) 4737edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-2') 4738edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.min_mag(Decimal('-3'), Decimal('NaN')) 4739edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-3') 4740edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.min_mag(1, -2) 4741edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4742edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.min_mag(Decimal(1), -2) 4743edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4744edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.min_mag(1, Decimal(-2)) 4745edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 4746edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4747edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4748edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.min_mag(b, context=self) 4749edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4750edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def minus(self, a): 4751edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Minus corresponds to unary prefix minus in Python. 4752edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4753edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The operation is evaluated using the same rules as subtract; the 4754edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep operation minus(a) is calculated as subtract('0', a) where the '0' 4755edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep has the same exponent as the operand. 4756edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4757edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.minus(Decimal('1.3')) 4758edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1.3') 4759edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.minus(Decimal('-1.3')) 4760edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.3') 4761edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.minus(1) 4762edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4763edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4764edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4765edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.__neg__(context=self) 4766edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4767edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def multiply(self, a, b): 4768edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """multiply multiplies two operands. 4769edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4770edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If either operand is a special value then the general rules apply. 4771edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Otherwise, the operands are multiplied together 4772edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('long multiplication'), resulting in a number which may be as long as 4773edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the sum of the lengths of the two operands. 4774edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4775edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3')) 4776edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3.60') 4777edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.multiply(Decimal('7'), Decimal('3')) 4778edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('21') 4779edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8')) 4780edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.72') 4781edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0')) 4782edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-0.0') 4783edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321')) 4784edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('4.28135971E+11') 4785edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.multiply(7, 7) 4786edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('49') 4787edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.multiply(Decimal(7), 7) 4788edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('49') 4789edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.multiply(7, Decimal(7)) 4790edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('49') 4791edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4792edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4793edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r = a.__mul__(b, context=self) 4794edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if r is NotImplemented: 4795edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise TypeError("Unable to convert %s to Decimal" % b) 4796edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 4797edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return r 4798edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4799edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def next_minus(self, a): 4800edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the largest representable number smaller than a. 4801edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4802edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c = ExtendedContext.copy() 4803edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emin = -999 4804edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emax = 999 4805edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.next_minus(Decimal('1')) 4806edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.999999999') 4807edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_minus(Decimal('1E-1007')) 4808edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0E-1007') 4809edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.next_minus(Decimal('-1.00000003')) 4810edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1.00000004') 4811edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_minus(Decimal('Infinity')) 4812edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('9.99999999E+999') 4813edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_minus(1) 4814edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.999999999') 4815edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4816edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4817edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.next_minus(context=self) 4818edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4819edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def next_plus(self, a): 4820edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the smallest representable number larger than a. 4821edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4822edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c = ExtendedContext.copy() 4823edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emin = -999 4824edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emax = 999 4825edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.next_plus(Decimal('1')) 4826edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.00000001') 4827edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_plus(Decimal('-1E-1007')) 4828edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-0E-1007') 4829edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.next_plus(Decimal('-1.00000003')) 4830edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1.00000002') 4831edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_plus(Decimal('-Infinity')) 4832edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-9.99999999E+999') 4833edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_plus(1) 4834edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.00000001') 4835edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4836edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4837edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.next_plus(context=self) 4838edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4839edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def next_toward(self, a, b): 4840edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the number closest to a, in direction towards b. 4841edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4842edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The result is the closest representable number from the first 4843edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep operand (but not the first operand) that is in the direction 4844edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep towards the second operand, unless the operands have the same 4845edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep value. 4846edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4847edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c = ExtendedContext.copy() 4848edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emin = -999 4849edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emax = 999 4850edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_toward(Decimal('1'), Decimal('2')) 4851edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.00000001') 4852edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_toward(Decimal('-1E-1007'), Decimal('1')) 4853edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-0E-1007') 4854edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_toward(Decimal('-1.00000003'), Decimal('0')) 4855edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1.00000002') 4856edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_toward(Decimal('1'), Decimal('0')) 4857edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.999999999') 4858edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_toward(Decimal('1E-1007'), Decimal('-100')) 4859edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0E-1007') 4860edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_toward(Decimal('-1.00000003'), Decimal('-10')) 4861edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1.00000004') 4862edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_toward(Decimal('0.00'), Decimal('-0.0000')) 4863edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-0.00') 4864edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_toward(0, 1) 4865edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1E-1007') 4866edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_toward(Decimal(0), 1) 4867edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1E-1007') 4868edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.next_toward(0, Decimal(1)) 4869edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1E-1007') 4870edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4871edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4872edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.next_toward(b, context=self) 4873edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4874edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def normalize(self, a): 4875edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """normalize reduces an operand to its simplest form. 4876edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4877edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Essentially a plus operation with all trailing zeros removed from the 4878edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result. 4879edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4880edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.normalize(Decimal('2.1')) 4881edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.1') 4882edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.normalize(Decimal('-2.0')) 4883edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-2') 4884edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.normalize(Decimal('1.200')) 4885edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.2') 4886edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.normalize(Decimal('-120')) 4887edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1.2E+2') 4888edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.normalize(Decimal('120.00')) 4889edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.2E+2') 4890edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.normalize(Decimal('0.00')) 4891edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 4892edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.normalize(6) 4893edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('6') 4894edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4895edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4896edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.normalize(context=self) 4897edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4898edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def number_class(self, a): 4899edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns an indication of the class of the operand. 4900edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4901edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The class is one of the following strings: 4902edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -sNaN 4903edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -NaN 4904edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -Infinity 4905edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -Normal 4906edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -Subnormal 4907edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -Zero 4908edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep +Zero 4909edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep +Subnormal 4910edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep +Normal 4911edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep +Infinity 4912edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4913edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c = Context(ExtendedContext) 4914edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emin = -999 4915edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emax = 999 4916edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.number_class(Decimal('Infinity')) 4917edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '+Infinity' 4918edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.number_class(Decimal('1E-10')) 4919edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '+Normal' 4920edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.number_class(Decimal('2.50')) 4921edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '+Normal' 4922edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.number_class(Decimal('0.1E-999')) 4923edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '+Subnormal' 4924edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.number_class(Decimal('0')) 4925edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '+Zero' 4926edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.number_class(Decimal('-0')) 4927edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '-Zero' 4928edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.number_class(Decimal('-0.1E-999')) 4929edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '-Subnormal' 4930edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.number_class(Decimal('-1E-10')) 4931edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '-Normal' 4932edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.number_class(Decimal('-2.50')) 4933edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '-Normal' 4934edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.number_class(Decimal('-Infinity')) 4935edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '-Infinity' 4936edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.number_class(Decimal('NaN')) 4937edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'NaN' 4938edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.number_class(Decimal('-NaN')) 4939edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'NaN' 4940edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.number_class(Decimal('sNaN')) 4941edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'sNaN' 4942edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.number_class(123) 4943edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '+Normal' 4944edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4945edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4946edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.number_class(context=self) 4947edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4948edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def plus(self, a): 4949edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Plus corresponds to unary prefix plus in Python. 4950edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4951edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The operation is evaluated using the same rules as add; the 4952edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep operation plus(a) is calculated as add('0', a) where the '0' 4953edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep has the same exponent as the operand. 4954edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4955edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.plus(Decimal('1.3')) 4956edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.3') 4957edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.plus(Decimal('-1.3')) 4958edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1.3') 4959edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.plus(-1) 4960edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 4961edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 4962edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 4963edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.__pos__(context=self) 4964edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4965edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def power(self, a, b, modulo=None): 4966edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Raises a to the power of b, to modulo if given. 4967edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4968edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep With two arguments, compute a**b. If a is negative then b 4969edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep must be integral. The result will be inexact unless b is 4970edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep integral and the result is finite and can be expressed exactly 4971edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep in 'precision' digits. 4972edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4973edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep With three arguments, compute (a**b) % modulo. For the 4974edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep three argument form, the following restrictions on the 4975edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep arguments hold: 4976edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4977edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep - all three arguments must be integral 4978edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep - b must be nonnegative 4979edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep - at least one of a or b must be nonzero 4980edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep - modulo must be nonzero and have at most 'precision' digits 4981edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4982edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The result of pow(a, b, modulo) is identical to the result 4983edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep that would be obtained by computing (a**b) % modulo with 4984edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unbounded precision, but is computed more efficiently. It is 4985edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep always exact. 4986edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4987edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c = ExtendedContext.copy() 4988edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emin = -999 4989edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.Emax = 999 4990edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('2'), Decimal('3')) 4991edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('8') 4992edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('-2'), Decimal('3')) 4993edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-8') 4994edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('2'), Decimal('-3')) 4995edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.125') 4996edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('1.7'), Decimal('8')) 4997edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('69.7575744') 4998edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('10'), Decimal('0.301029996')) 4999edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.00000000') 5000edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('Infinity'), Decimal('-1')) 5001edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 5002edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('Infinity'), Decimal('0')) 5003edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 5004edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('Infinity'), Decimal('1')) 5005edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('Infinity') 5006edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('-Infinity'), Decimal('-1')) 5007edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-0') 5008edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('-Infinity'), Decimal('0')) 5009edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 5010edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('-Infinity'), Decimal('1')) 5011edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-Infinity') 5012edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('-Infinity'), Decimal('2')) 5013edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('Infinity') 5014edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('0'), Decimal('0')) 5015edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('NaN') 5016edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5017edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('3'), Decimal('7'), Decimal('16')) 5018edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('11') 5019edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('-3'), Decimal('7'), Decimal('16')) 5020edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-11') 5021edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('-3'), Decimal('8'), Decimal('16')) 5022edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 5023edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('3'), Decimal('7'), Decimal('-16')) 5024edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('11') 5025edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('23E12345'), Decimal('67E189'), Decimal('123456789')) 5026edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('11729830') 5027edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('-0'), Decimal('17'), Decimal('1729')) 5028edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-0') 5029edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> c.power(Decimal('-23'), Decimal('0'), Decimal('65537')) 5030edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 5031edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.power(7, 7) 5032edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('823543') 5033edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.power(Decimal(7), 7) 5034edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('823543') 5035edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.power(7, Decimal(7), 2) 5036edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 5037edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5038edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 5039edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r = a.__pow__(b, modulo, context=self) 5040edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if r is NotImplemented: 5041edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise TypeError("Unable to convert %s to Decimal" % b) 5042edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5043edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return r 5044edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5045edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def quantize(self, a, b): 5046edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns a value equal to 'a' (rounded), having the exponent of 'b'. 5047edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5048edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The coefficient of the result is derived from that of the left-hand 5049edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep operand. It may be rounded using the current rounding setting (if the 5050edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exponent is being increased), multiplied by a positive power of ten (if 5051edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the exponent is being decreased), or is unchanged (if the exponent is 5052edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep already equal to that of the right-hand operand). 5053edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5054edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Unlike other operations, if the length of the coefficient after the 5055edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep quantize operation would be greater than precision then an Invalid 5056edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep operation condition is raised. This guarantees that, unless there is 5057edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep an error condition, the exponent of the result of a quantize is always 5058edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep equal to that of the right-hand operand. 5059edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5060edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Also unlike other operations, quantize will never raise Underflow, even 5061edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if the result is subnormal and inexact. 5062edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5063edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001')) 5064edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.170') 5065edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01')) 5066edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.17') 5067edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1')) 5068edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.2') 5069edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0')) 5070edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2') 5071edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1')) 5072edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0E+1') 5073edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity')) 5074edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-Infinity') 5075edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity')) 5076edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('NaN') 5077edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1')) 5078edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-0') 5079edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5')) 5080edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-0E+5') 5081edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2')) 5082edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('NaN') 5083edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2')) 5084edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('NaN') 5085edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1')) 5086edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('217.0') 5087edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0')) 5088edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('217') 5089edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1')) 5090edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.2E+2') 5091edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2')) 5092edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2E+2') 5093edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(1, 2) 5094edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 5095edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(Decimal(1), 2) 5096edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 5097edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.quantize(1, Decimal(2)) 5098edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 5099edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 5101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.quantize(b, context=self) 5102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def radix(self): 5104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Just returns 10, as this is Decimal, :) 5105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.radix() 5107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('10') 5108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(10) 5110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def remainder(self, a, b): 5112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the remainder from integer division. 5113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The result is the residue of the dividend after the operation of 5115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep calculating integer division as described for divide-integer, rounded 5116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep to precision digits if necessary. The sign of the result, if 5117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep non-zero, is the same as that of the original dividend. 5118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This operation will fail under the same conditions as integer division 5120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (that is, if integer division on the same two operands would fail, the 5121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep remainder cannot be calculated). 5122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3')) 5124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.1') 5125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder(Decimal('10'), Decimal('3')) 5126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 5127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3')) 5128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 5129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1')) 5130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.2') 5131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3')) 5132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.1') 5133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3')) 5134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.0') 5135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder(22, 6) 5136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('4') 5137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder(Decimal(22), 6) 5138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('4') 5139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder(22, Decimal(6)) 5140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('4') 5141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 5143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r = a.__mod__(b, context=self) 5144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if r is NotImplemented: 5145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise TypeError("Unable to convert %s to Decimal" % b) 5146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return r 5148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def remainder_near(self, a, b): 5150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns to be "a - b * n", where n is the integer nearest the exact 5151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep value of "x / b" (if two integers are equally near then the even one 5152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep is chosen). If the result is equal to 0 then its sign will be the 5153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign of a. 5154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This operation will fail under the same conditions as integer division 5156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (that is, if integer division on the same two operands would fail, the 5157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep remainder cannot be calculated). 5158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3')) 5160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-0.9') 5161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6')) 5162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-2') 5163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3')) 5164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 5165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3')) 5166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-1') 5167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1')) 5168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.2') 5169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3')) 5170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.1') 5171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3')) 5172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-0.3') 5173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder_near(3, 11) 5174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3') 5175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder_near(Decimal(3), 11) 5176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3') 5177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.remainder_near(3, Decimal(11)) 5178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3') 5179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 5181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.remainder_near(b, context=self) 5182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def rotate(self, a, b): 5184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns a rotated copy of a, b times. 5185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The coefficient of the result is a rotated copy of the digits in 5187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the coefficient of the first operand. The number of places of 5188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rotation is taken from the absolute value of the second operand, 5189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep with the rotation being to the left if the second operand is 5190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep positive or to the right otherwise. 5191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.rotate(Decimal('34'), Decimal('8')) 5193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('400000003') 5194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.rotate(Decimal('12'), Decimal('9')) 5195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('12') 5196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('-2')) 5197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('891234567') 5198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('0')) 5199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('123456789') 5200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('+2')) 5201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('345678912') 5202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.rotate(1333333, 1) 5203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('13333330') 5204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.rotate(Decimal(1333333), 1) 5205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('13333330') 5206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.rotate(1333333, Decimal(1)) 5207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('13333330') 5208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 5210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.rotate(b, context=self) 5211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def same_quantum(self, a, b): 5213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns True if the two operands have the same exponent. 5214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The result is never affected by either the sign or the coefficient of 5216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep either operand. 5217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001')) 5219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 5220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01')) 5221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 5222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1')) 5223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep False 5224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf')) 5225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 5226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.same_quantum(10000, -1) 5227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 5228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.same_quantum(Decimal(10000), -1) 5229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 5230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.same_quantum(10000, Decimal(-1)) 5231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep True 5232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 5234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.same_quantum(b) 5235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def scaleb (self, a, b): 5237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns the first operand after adding the second value its exp. 5238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('-2')) 5240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.0750') 5241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('0')) 5242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('7.50') 5243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('3')) 5244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('7.50E+3') 5245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.scaleb(1, 4) 5246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1E+4') 5247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.scaleb(Decimal(1), 4) 5248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1E+4') 5249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.scaleb(1, Decimal(4)) 5250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1E+4') 5251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 5253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.scaleb(b, context=self) 5254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def shift(self, a, b): 5256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Returns a shifted copy of a, b times. 5257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The coefficient of the result is a shifted copy of the digits 5259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep in the coefficient of the first operand. The number of places 5260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep to shift is taken from the absolute value of the second operand, 5261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep with the shift being to the left if the second operand is 5262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep positive or to the right otherwise. Digits shifted into the 5263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coefficient are zeros. 5264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.shift(Decimal('34'), Decimal('8')) 5266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('400000000') 5267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.shift(Decimal('12'), Decimal('9')) 5268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 5269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.shift(Decimal('123456789'), Decimal('-2')) 5270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1234567') 5271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.shift(Decimal('123456789'), Decimal('0')) 5272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('123456789') 5273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.shift(Decimal('123456789'), Decimal('+2')) 5274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('345678900') 5275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.shift(88888888, 2) 5276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('888888800') 5277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.shift(Decimal(88888888), 2) 5278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('888888800') 5279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.shift(88888888, Decimal(2)) 5280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('888888800') 5281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 5283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.shift(b, context=self) 5284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def sqrt(self, a): 5286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Square root of a non-negative number to context precision. 5287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If the result must be inexact, it is rounded using the round-half-even 5289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep algorithm. 5290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.sqrt(Decimal('0')) 5292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0') 5293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.sqrt(Decimal('-0')) 5294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-0') 5295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.sqrt(Decimal('0.39')) 5296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.624499800') 5297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.sqrt(Decimal('100')) 5298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('10') 5299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.sqrt(Decimal('1')) 5300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1') 5301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.sqrt(Decimal('1.0')) 5302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.0') 5303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.sqrt(Decimal('1.00')) 5304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.0') 5305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.sqrt(Decimal('7')) 5306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2.64575131') 5307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.sqrt(Decimal('10')) 5308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3.16227766') 5309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.sqrt(2) 5310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.41421356') 5311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.prec 5312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 9 5313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 5315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.sqrt(context=self) 5316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def subtract(self, a, b): 5318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Return the difference between the two operands. 5319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07')) 5321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.23') 5322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30')) 5323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('0.00') 5324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07')) 5325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-0.77') 5326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.subtract(8, 5) 5327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3') 5328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.subtract(Decimal(8), 5) 5329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3') 5330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.subtract(8, Decimal(5)) 5331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('3') 5332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 5334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r = a.__sub__(b, context=self) 5335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if r is NotImplemented: 5336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise TypeError("Unable to convert %s to Decimal" % b) 5337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return r 5339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def to_eng_string(self, a): 5341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Converts a number to a string, using scientific notation. 5342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The operation is not affected by the context. 5344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 5346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.to_eng_string(context=self) 5347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def to_sci_string(self, a): 5349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Converts a number to a string, using scientific notation. 5350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The operation is not affected by the context. 5352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 5354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.__str__(context=self) 5355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def to_integral_exact(self, a): 5357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Rounds to an integer. 5358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep When the operand has a negative exponent, the result is the same 5360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep as using the quantize() operation using the given operand as the 5361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep left-hand-operand, 1E+0 as the right-hand-operand, and the precision 5362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep of the operand as the precision setting; Inexact and Rounded flags 5363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep are allowed in this operation. The rounding mode is taken from the 5364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep context. 5365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_exact(Decimal('2.1')) 5367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2') 5368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_exact(Decimal('100')) 5369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('100') 5370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_exact(Decimal('100.0')) 5371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('100') 5372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_exact(Decimal('101.5')) 5373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('102') 5374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_exact(Decimal('-101.5')) 5375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-102') 5376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_exact(Decimal('10E+5')) 5377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.0E+6') 5378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_exact(Decimal('7.89E+77')) 5379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('7.89E+77') 5380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_exact(Decimal('-Inf')) 5381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-Infinity') 5382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 5384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.to_integral_exact(context=self) 5385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def to_integral_value(self, a): 5387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Rounds to an integer. 5388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep When the operand has a negative exponent, the result is the same 5390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep as using the quantize() operation using the given operand as the 5391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep left-hand-operand, 1E+0 as the right-hand-operand, and the precision 5392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep of the operand as the precision setting, except that no flags will 5393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep be set. The rounding mode is taken from the context. 5394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_value(Decimal('2.1')) 5396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('2') 5397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_value(Decimal('100')) 5398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('100') 5399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_value(Decimal('100.0')) 5400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('100') 5401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_value(Decimal('101.5')) 5402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('102') 5403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_value(Decimal('-101.5')) 5404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-102') 5405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_value(Decimal('10E+5')) 5406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('1.0E+6') 5407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_value(Decimal('7.89E+77')) 5408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('7.89E+77') 5409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> ExtendedContext.to_integral_value(Decimal('-Inf')) 5410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal('-Infinity') 5411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = _convert_other(a, raiseit=True) 5413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a.to_integral_value(context=self) 5414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the method name changed, but we provide also the old one, for compatibility 5416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep to_integral = to_integral_value 5417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass _WorkRep(object): 5419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep __slots__ = ('sign','int','exp') 5420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # sign: 0 or 1 5421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # int: int or long 5422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # exp: None, int, or string 5423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __init__(self, value=None): 5425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if value is None: 5426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.sign = None 5427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.int = 0 5428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.exp = None 5429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif isinstance(value, Decimal): 5430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.sign = value._sign 5431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.int = int(value._int) 5432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.exp = value._exp 5433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # assert isinstance(value, tuple) 5435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.sign = value[0] 5436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.int = value[1] 5437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.exp = value[2] 5438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __repr__(self): 5440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return "(%r, %r, %r)" % (self.sign, self.int, self.exp) 5441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep __str__ = __repr__ 5443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _normalize(op1, op2, prec = 0): 5447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Normalizes op1, op2 to have the same exp and length of coefficient. 5448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Done during addition. 5450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if op1.exp < op2.exp: 5452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep tmp = op2 5453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = op1 5454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep tmp = op1 5456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other = op2 5457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Let exp = min(tmp.exp - 1, tmp.adjusted() - precision - 1). 5459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Then adding 10**exp to tmp has the same effect (after rounding) 5460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # as adding any positive quantity smaller than 10**exp; similarly 5461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # for subtraction. So if other is smaller than 10**exp we replace 5462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # it with 10**exp. This avoids tmp.exp - other.exp getting too large. 5463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep tmp_len = len(str(tmp.int)) 5464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other_len = len(str(other.int)) 5465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp = tmp.exp + min(-1, tmp_len - prec - 2) 5466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if other_len + other.exp - 1 < exp: 5467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other.int = 1 5468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep other.exp = exp 5469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep tmp.int *= 10 ** (tmp.exp - other.exp) 5471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep tmp.exp = other.exp 5472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return op1, op2 5473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### Integer arithmetic functions used by ln, log10, exp and __pow__ ##### 5475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# This function from Tim Peters was taken from here: 5477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# http://mail.python.org/pipermail/python-list/1999-July/007758.html 5478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# The correction being in the function definition is for speed, and 5479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# the whole function is not resolved with math.log because of avoiding 5480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# the use of floats. 5481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _nbits(n, correction = { 5482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '0': 4, '1': 3, '2': 2, '3': 2, 5483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '4': 1, '5': 1, '6': 1, '7': 1, 5484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '8': 0, '9': 0, 'a': 0, 'b': 0, 5485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'c': 0, 'd': 0, 'e': 0, 'f': 0}): 5486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Number of bits in binary representation of the positive integer n, 5487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep or 0 if n == 0. 5488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if n < 0: 5490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError("The argument to _nbits should be nonnegative.") 5491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep hex_n = "%x" % n 5492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 4*len(hex_n) - correction[hex_n[0]] 5493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _decimal_lshift_exact(n, e): 5495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ Given integers n and e, return n * 10**e if it's an integer, else None. 5496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The computation is designed to avoid computing large powers of 10 5498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unnecessarily. 5499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> _decimal_lshift_exact(3, 4) 5501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 30000 5502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep >>> _decimal_lshift_exact(300, -999999999) # returns None 5503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if n == 0: 5506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 0 5507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif e >= 0: 5508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return n * 10**e 5509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # val_n = largest power of 10 dividing n. 5511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep str_n = str(abs(n)) 5512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep val_n = len(str_n) - len(str_n.rstrip('0')) 5513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return None if val_n < -e else n // 10**-e 5514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _sqrt_nearest(n, a): 5516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Closest integer to the square root of the positive integer n. a is 5517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep an initial approximation to the square root. Any positive integer 5518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep will do for a, but the closer a is to the square root of n the 5519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep faster convergence will be. 5520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if n <= 0 or a <= 0: 5523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError("Both arguments to _sqrt_nearest should be positive.") 5524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep b=0 5526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while a != b: 5527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep b, a = a, a--n//a>>1 5528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return a 5529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _rshift_nearest(x, shift): 5531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Given an integer x and a nonnegative integer shift, return closest 5532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep integer to x / 2**shift; use round-to-even in case of a tie. 5533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep b, q = 1L << shift, x >> shift 5536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return q + (2*(x & (b-1)) + (q&1) > b) 5537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _div_nearest(a, b): 5539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Closest integer to a/b, a and b positive integers; rounds to even 5540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep in the case of a tie. 5541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep q, r = divmod(a, b) 5544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return q + (2*r + (q&1) > b) 5545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _ilog(x, M, L = 8): 5547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Integer approximation to M*log(x/M), with absolute error boundable 5548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep in terms only of x/M. 5549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Given positive integers x and M, return an integer approximation to 5551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep M * log(x/M). For L = 8 and 0.1 <= x/M <= 10 the difference 5552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep between the approximation and the exact result is at most 22. For 5553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep L = 8 and 1.0 <= x/M <= 10.0 the difference is at most 15. In 5554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep both cases these are upper bounds on the error; it will usually be 5555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep much smaller.""" 5556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # The basic algorithm is the following: let log1p be the function 5558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # log1p(x) = log(1+x). Then log(x/M) = log1p((x-M)/M). We use 5559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the reduction 5560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 5561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # log1p(y) = 2*log1p(y/(1+sqrt(1+y))) 5562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 5563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # repeatedly until the argument to log1p is small (< 2**-L in 5564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # absolute value). For small y we can use the Taylor series 5565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # expansion 5566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 5567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # log1p(y) ~ y - y**2/2 + y**3/3 - ... - (-y)**T/T 5568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 5569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # truncating at T such that y**T is small enough. The whole 5570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # computation is carried out in a form of fixed-point arithmetic, 5571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # with a real number z being represented by an integer 5572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # approximation to z*M. To avoid loss of precision, the y below 5573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # is actually an integer approximation to 2**R*y*M, where R is the 5574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # number of reductions performed so far. 5575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep y = x-M 5577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # argument reduction; R = number of reductions performed 5578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep R = 0 5579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while (R <= L and long(abs(y)) << L-R >= M or 5580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep R > L and abs(y) >> R-L >= M): 5581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep y = _div_nearest(long(M*y) << 1, 5582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep M + _sqrt_nearest(M*(M+_rshift_nearest(y, R)), M)) 5583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep R += 1 5584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Taylor series with T terms 5586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep T = -int(-10*len(str(M))//(3*L)) 5587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep yshift = _rshift_nearest(y, R) 5588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep w = _div_nearest(M, T) 5589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for k in xrange(T-1, 0, -1): 5590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep w = _div_nearest(M, k) - _div_nearest(yshift*w, M) 5591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _div_nearest(w*y, M) 5593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _dlog10(c, e, p): 5595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Given integers c, e and p with c > 0, p >= 0, compute an integer 5596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep approximation to 10**p * log10(c*10**e), with an absolute error of 5597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep at most 1. Assumes that c*10**e is not exactly 1.""" 5598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # increase precision by 2; compensate for this by dividing 5600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # final result by 100 5601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep p += 2 5602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # write c*10**e as d*10**f with either: 5604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # f >= 0 and 1 <= d <= 10, or 5605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # f <= 0 and 0.1 <= d <= 1. 5606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Thus for c*10**e close to 1, f = 0 5607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep l = len(str(c)) 5608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep f = e+l - (e+l >= 1) 5609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if p > 0: 5611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep M = 10**p 5612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep k = e+p-f 5613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if k >= 0: 5614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c *= 10**k 5615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = _div_nearest(c, 10**-k) 5617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep log_d = _ilog(c, M) # error < 5 + 22 = 27 5619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep log_10 = _log10_digits(p) # error < 1 5620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep log_d = _div_nearest(log_d*M, log_10) 5621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep log_tenpower = f*M # exact 5622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep log_d = 0 # error < 2.31 5624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep log_tenpower = _div_nearest(f, 10**-p) # error < 0.5 5625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _div_nearest(log_tenpower+log_d, 100) 5627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _dlog(c, e, p): 5629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Given integers c, e and p with c > 0, compute an integer 5630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep approximation to 10**p * log(c*10**e), with an absolute error of 5631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep at most 1. Assumes that c*10**e is not exactly 1.""" 5632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Increase precision by 2. The precision increase is compensated 5634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # for at the end with a division by 100. 5635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep p += 2 5636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # rewrite c*10**e as d*10**f with either f >= 0 and 1 <= d <= 10, 5638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # or f <= 0 and 0.1 <= d <= 1. Then we can compute 10**p * log(c*10**e) 5639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # as 10**p * log(d) + 10**p*f * log(10). 5640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep l = len(str(c)) 5641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep f = e+l - (e+l >= 1) 5642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute approximation to 10**p*log(d), with error < 27 5644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if p > 0: 5645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep k = e+p-f 5646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if k >= 0: 5647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c *= 10**k 5648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = _div_nearest(c, 10**-k) # error of <= 0.5 in c 5650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # _ilog magnifies existing error in c by a factor of at most 10 5652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep log_d = _ilog(c, 10**p) # error < 5 + 22 = 27 5653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # p <= 0: just approximate the whole thing by 0; error < 2.31 5655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep log_d = 0 5656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute approximation to f*10**p*log(10), with error < 11. 5658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if f: 5659edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep extra = len(str(abs(f)))-1 5660edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if p + extra >= 0: 5661edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # error in f * _log10_digits(p+extra) < |f| * 1 = |f| 5662edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # after division, error < |f|/10**extra + 0.5 < 10 + 0.5 < 11 5663edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep f_log_ten = _div_nearest(f*_log10_digits(p+extra), 10**extra) 5664edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5665edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep f_log_ten = 0 5666edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5667edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep f_log_ten = 0 5668edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5669edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # error in sum < 11+27 = 38; error after division < 0.38 + 0.5 < 1 5670edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _div_nearest(f_log_ten + log_d, 100) 5671edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5672edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass _Log10Memoize(object): 5673edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Class to compute, store, and allow retrieval of, digits of the 5674edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep constant log(10) = 2.302585.... This constant is needed by 5675edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Decimal.ln, Decimal.log10, Decimal.exp and Decimal.__pow__.""" 5676edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __init__(self): 5677edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.digits = "23025850929940456840179914546843642076011014886" 5678edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5679edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def getdigits(self, p): 5680edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Given an integer p >= 0, return floor(10**p)*log(10). 5681edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5682edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep For example, self.getdigits(3) returns 2302. 5683edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5684edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # digits are stored as a string, for quick conversion to 5685edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # integer in the case that we've already computed enough 5686edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # digits; the stored digits should always be correct 5687edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # (truncated, not rounded to nearest). 5688edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if p < 0: 5689edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError("p should be nonnegative") 5690edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5691edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if p >= len(self.digits): 5692edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute p+3, p+6, p+9, ... digits; continue until at 5693edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # least one of the extra digits is nonzero 5694edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep extra = 3 5695edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while True: 5696edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute p+extra digits, correct to within 1ulp 5697edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep M = 10**(p+extra+2) 5698edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep digits = str(_div_nearest(_ilog(10*M, M), 100)) 5699edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if digits[-extra:] != '0'*extra: 5700edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep break 5701edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep extra += 3 5702edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # keep all reliable digits so far; remove trailing zeros 5703edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # and next nonzero digit 5704edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.digits = digits.rstrip('0')[:-1] 5705edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return int(self.digits[:p+1]) 5706edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5707edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_log10_digits = _Log10Memoize().getdigits 5708edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5709edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _iexp(x, M, L=8): 5710edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Given integers x and M, M > 0, such that x/M is small in absolute 5711edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep value, compute an integer approximation to M*exp(x/M). For 0 <= 5712edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep x/M <= 2.4, the absolute error in the result is bounded by 60 (and 5713edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep is usually much smaller).""" 5714edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5715edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Algorithm: to compute exp(z) for a real number z, first divide z 5716edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # by a suitable power R of 2 so that |z/2**R| < 2**-L. Then 5717edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute expm1(z/2**R) = exp(z/2**R) - 1 using the usual Taylor 5718edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # series 5719edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 5720edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # expm1(x) = x + x**2/2! + x**3/3! + ... 5721edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 5722edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Now use the identity 5723edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 5724edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # expm1(2x) = expm1(x)*(expm1(x)+2) 5725edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 5726edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # R times to compute the sequence expm1(z/2**R), 5727edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # expm1(z/2**(R-1)), ... , exp(z/2), exp(z). 5728edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5729edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Find R such that x/2**R/M <= 2**-L 5730edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep R = _nbits((long(x)<<L)//M) 5731edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5732edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Taylor series. (2**L)**T > M 5733edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep T = -int(-10*len(str(M))//(3*L)) 5734edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep y = _div_nearest(x, T) 5735edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Mshift = long(M)<<R 5736edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for i in xrange(T-1, 0, -1): 5737edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep y = _div_nearest(x*(Mshift + y), Mshift * i) 5738edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5739edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Expansion 5740edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for k in xrange(R-1, -1, -1): 5741edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Mshift = long(M)<<(k+2) 5742edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep y = _div_nearest(y*(y+Mshift), Mshift) 5743edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5744edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return M+y 5745edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5746edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _dexp(c, e, p): 5747edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compute an approximation to exp(c*10**e), with p decimal places of 5748edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep precision. 5749edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5750edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Returns integers d, f such that: 5751edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5752edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 10**(p-1) <= d <= 10**p, and 5753edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (d-1)*10**f < exp(c*10**e) < (d+1)*10**f 5754edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5755edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep In other words, d*10**f is an approximation to exp(c*10**e) with p 5756edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep digits of precision, and with an error in d of at most 1. This is 5757edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep almost, but not quite, the same as the error being < 1ulp: when d 5758edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep = 10**(p-1) the error could be up to 10 ulp.""" 5759edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5760edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # we'll call iexp with M = 10**(p+2), giving p+3 digits of precision 5761edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep p += 2 5762edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5763edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute log(10) with extra precision = adjusted exponent of c*10**e 5764edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep extra = max(0, e + len(str(c)) - 1) 5765edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep q = p + extra 5766edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5767edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute quotient c*10**e/(log(10)) = c*10**(e+q)/(log(10)*10**q), 5768edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # rounding down 5769edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep shift = e+q 5770edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if shift >= 0: 5771edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep cshift = c*10**shift 5772edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5773edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep cshift = c//10**-shift 5774edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep quot, rem = divmod(cshift, _log10_digits(q)) 5775edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5776edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # reduce remainder back to original precision 5777edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep rem = _div_nearest(rem, 10**extra) 5778edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5779edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # error in result of _iexp < 120; error after division < 0.62 5780edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _div_nearest(_iexp(rem, 10**p), 1000), quot - p + 3 5781edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5782edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _dpower(xc, xe, yc, ye, p): 5783edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Given integers xc, xe, yc and ye representing Decimals x = xc*10**xe and 5784edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep y = yc*10**ye, compute x**y. Returns a pair of integers (c, e) such that: 5785edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5786edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 10**(p-1) <= c <= 10**p, and 5787edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (c-1)*10**e < x**y < (c+1)*10**e 5788edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5789edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep in other words, c*10**e is an approximation to x**y with p digits 5790edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep of precision, and with an error in c of at most 1. (This is 5791edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep almost, but not quite, the same as the error being < 1ulp: when c 5792edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep == 10**(p-1) we can only guarantee error < 10ulp.) 5793edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5794edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep We assume that: x is positive and not equal to 1, and y is nonzero. 5795edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5796edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5797edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Find b such that 10**(b-1) <= |y| <= 10**b 5798edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep b = len(str(abs(yc))) + ye 5799edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5800edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # log(x) = lxc*10**(-p-b-1), to p+b+1 places after the decimal point 5801edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep lxc = _dlog(xc, xe, p+b+1) 5802edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5803edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # compute product y*log(x) = yc*lxc*10**(-p-b-1+ye) = pc*10**(-p-1) 5804edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep shift = ye-b 5805edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if shift >= 0: 5806edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep pc = lxc*yc*10**shift 5807edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5808edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep pc = _div_nearest(lxc*yc, 10**-shift) 5809edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5810edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if pc == 0: 5811edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # we prefer a result that isn't exactly 1; this makes it 5812edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # easier to compute a correctly rounded result in __pow__ 5813edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ((len(str(xc)) + xe >= 1) == (yc > 0)): # if x**y > 1: 5814edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff, exp = 10**(p-1)+1, 1-p 5815edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5816edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff, exp = 10**p-1, -p 5817edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 5818edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff, exp = _dexp(pc, -(p+1), p+1) 5819edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep coeff = _div_nearest(coeff, 10) 5820edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp += 1 5821edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5822edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return coeff, exp 5823edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5824edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _log10_lb(c, correction = { 5825edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '1': 100, '2': 70, '3': 53, '4': 40, '5': 31, 5826edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '6': 23, '7': 16, '8': 10, '9': 5}): 5827edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Compute a lower bound for 100*log10(c) for a positive integer c.""" 5828edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if c <= 0: 5829edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError("The argument to _log10_lb should be nonnegative.") 5830edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep str_c = str(c) 5831edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 100*len(str_c) - correction[str_c[0]] 5832edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5833edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### Helper Functions #################################################### 5834edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5835edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _convert_other(other, raiseit=False, allow_float=False): 5836edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Convert other to Decimal. 5837edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5838edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Verifies that it's ok to use in an implicit construction. 5839edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If allow_float is true, allow conversion from float; this 5840edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep is used in the comparison methods (__eq__ and friends). 5841edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5842edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5843edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if isinstance(other, Decimal): 5844edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return other 5845edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if isinstance(other, (int, long)): 5846edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal(other) 5847edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if allow_float and isinstance(other, float): 5848edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Decimal.from_float(other) 5849edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5850edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if raiseit: 5851edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise TypeError("Unable to convert %s to Decimal" % other) 5852edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return NotImplemented 5853edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5854edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### Setup Specific Contexts ############################################ 5855edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5856edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# The default context prototype used by Context() 5857edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Is mutable, so that new contexts can have different default values 5858edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5859edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDefaultContext = Context( 5860edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep prec=28, rounding=ROUND_HALF_EVEN, 5861edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep traps=[DivisionByZero, Overflow, InvalidOperation], 5862edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep flags=[], 5863edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Emax=999999999, 5864edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Emin=-999999999, 5865edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep capitals=1 5866edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep) 5867edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5868edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Pre-made alternate contexts offered by the specification 5869edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Don't change these; the user should be able to select these 5870edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# contexts and be able to reproduce results from other implementations 5871edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# of the spec. 5872edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5873edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepBasicContext = Context( 5874edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep prec=9, rounding=ROUND_HALF_UP, 5875edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow], 5876edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep flags=[], 5877edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep) 5878edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5879edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepExtendedContext = Context( 5880edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep prec=9, rounding=ROUND_HALF_EVEN, 5881edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep traps=[], 5882edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep flags=[], 5883edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep) 5884edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5885edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5886edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### crud for parsing strings ############################################# 5887edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 5888edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Regular expression used for parsing numeric strings. Additional 5889edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# comments: 5890edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 5891edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 1. Uncomment the two '\s*' lines to allow leading and/or trailing 5892edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# whitespace. But note that the specification disallows whitespace in 5893edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# a numeric string. 5894edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 5895edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 2. For finite numbers (not infinities and NaNs) the body of the 5896edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# number between the optional sign and the optional exponent must have 5897edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# at least one decimal digit, possibly after the decimal point. The 5898edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# lookahead expression '(?=\d|\.\d)' checks this. 5899edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5900edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport re 5901edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_parser = re.compile(r""" # A numeric string consists of: 5902edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# \s* 5903edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (?P<sign>[-+])? # an optional sign, followed by either... 5904edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ( 5905edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (?=\d|\.\d) # ...a number (with at least one digit) 5906edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (?P<int>\d*) # having a (possibly empty) integer part 5907edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (\.(?P<frac>\d*))? # followed by an optional fractional part 5908edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (E(?P<exp>[-+]?\d+))? # followed by an optional exponent, or... 5909edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep | 5910edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Inf(inity)? # ...an infinity, or... 5911edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep | 5912edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (?P<signal>s)? # ...an (optionally signaling) 5913edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep NaN # NaN 5914edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (?P<diag>\d*) # with (possibly empty) diagnostic info. 5915edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ) 5916edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# \s* 5917edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep \Z 5918edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""", re.VERBOSE | re.IGNORECASE | re.UNICODE).match 5919edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5920edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_all_zeros = re.compile('0*$').match 5921edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_exact_half = re.compile('50*$').match 5922edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5923edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### PEP3101 support functions ############################################## 5924edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# The functions in this section have little to do with the Decimal 5925edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# class, and could potentially be reused or adapted for other pure 5926edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Python numeric classes that want to implement __format__ 5927edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 5928edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# A format specifier for Decimal looks like: 5929edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 5930edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# [[fill]align][sign][0][minimumwidth][,][.precision][type] 5931edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5932edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_parse_format_specifier_regex = re.compile(r"""\A 5933edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep(?: 5934edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (?P<fill>.)? 5935edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (?P<align>[<>=^]) 5936edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep)? 5937edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep(?P<sign>[-+ ])? 5938edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep(?P<zeropad>0)? 5939edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep(?P<minimumwidth>(?!0)\d+)? 5940edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep(?P<thousands_sep>,)? 5941edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep(?:\.(?P<precision>0|(?!0)\d+))? 5942edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep(?P<type>[eEfFgGn%])? 5943edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\Z 5944edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""", re.VERBOSE) 5945edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5946edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdel re 5947edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5948edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# The locale module is only needed for the 'n' format specifier. The 5949edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# rest of the PEP 3101 code functions quite happily without it, so we 5950edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# don't care too much if locale isn't present. 5951edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoeptry: 5952edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep import locale as _locale 5953edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepexcept ImportError: 5954edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep pass 5955edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5956edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _parse_format_specifier(format_spec, _localeconv=None): 5957edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Parse and validate a format specifier. 5958edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5959edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Turns a standard numeric format specifier into a dict, with the 5960edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep following entries: 5961edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5962edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fill: fill character to pad field to minimum width 5963edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep align: alignment type, either '<', '>', '=' or '^' 5964edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign: either '+', '-' or ' ' 5965edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep minimumwidth: nonnegative integer giving minimum width 5966edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep zeropad: boolean, indicating whether to pad with zeros 5967edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep thousands_sep: string to use as thousands separator, or '' 5968edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep grouping: grouping for thousands separators, in format 5969edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep used by localeconv 5970edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep decimal_point: string to use for decimal point 5971edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep precision: nonnegative integer giving precision, or None 5972edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep type: one of the characters 'eEfFgG%', or None 5973edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unicode: boolean (always True for Python 3.x) 5974edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5975edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 5976edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = _parse_format_specifier_regex.match(format_spec) 5977edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if m is None: 5978edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError("Invalid format specifier: " + format_spec) 5979edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5980edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # get the dictionary 5981edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict = m.groupdict() 5982edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5983edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # zeropad; defaults for fill and alignment. If zero padding 5984edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # is requested, the fill and align fields should be absent. 5985edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fill = format_dict['fill'] 5986edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep align = format_dict['align'] 5987edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict['zeropad'] = (format_dict['zeropad'] is not None) 5988edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if format_dict['zeropad']: 5989edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if fill is not None: 5990edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError("Fill character conflicts with '0'" 5991edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep " in format specifier: " + format_spec) 5992edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if align is not None: 5993edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError("Alignment conflicts with '0' in " 5994edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "format specifier: " + format_spec) 5995edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict['fill'] = fill or ' ' 5996edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # PEP 3101 originally specified that the default alignment should 5997edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # be left; it was later agreed that right-aligned makes more sense 5998edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # for numeric types. See http://bugs.python.org/issue6857. 5999edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict['align'] = align or '>' 6000edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6001edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # default sign handling: '-' for negative, '' for positive 6002edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if format_dict['sign'] is None: 6003edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict['sign'] = '-' 6004edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6005edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # minimumwidth defaults to 0; precision remains None if not given 6006edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict['minimumwidth'] = int(format_dict['minimumwidth'] or '0') 6007edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if format_dict['precision'] is not None: 6008edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict['precision'] = int(format_dict['precision']) 6009edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6010edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # if format type is 'g' or 'G' then a precision of 0 makes little 6011edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # sense; convert it to 1. Same if format type is unspecified. 6012edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if format_dict['precision'] == 0: 6013edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if format_dict['type'] is None or format_dict['type'] in 'gG': 6014edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict['precision'] = 1 6015edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6016edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # determine thousands separator, grouping, and decimal separator, and 6017edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # add appropriate entries to format_dict 6018edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if format_dict['type'] == 'n': 6019edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # apart from separators, 'n' behaves just like 'g' 6020edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict['type'] = 'g' 6021edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if _localeconv is None: 6022edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep _localeconv = _locale.localeconv() 6023edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if format_dict['thousands_sep'] is not None: 6024edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError("Explicit thousands separator conflicts with " 6025edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "'n' type in format specifier: " + format_spec) 6026edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict['thousands_sep'] = _localeconv['thousands_sep'] 6027edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict['grouping'] = _localeconv['grouping'] 6028edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict['decimal_point'] = _localeconv['decimal_point'] 6029edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 6030edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if format_dict['thousands_sep'] is None: 6031edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict['thousands_sep'] = '' 6032edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict['grouping'] = [3, 0] 6033edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict['decimal_point'] = '.' 6034edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6035edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # record whether return type should be str or unicode 6036edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format_dict['unicode'] = isinstance(format_spec, unicode) 6037edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6038edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return format_dict 6039edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6040edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _format_align(sign, body, spec): 6041edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Given an unpadded, non-aligned numeric string 'body' and sign 6042edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep string 'sign', add padding and alignment conforming to the given 6043edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format specifier dictionary 'spec' (as produced by 6044edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep parse_format_specifier). 6045edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6046edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Also converts result to unicode if necessary. 6047edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6048edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 6049edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # how much extra space do we have to play with? 6050edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep minimumwidth = spec['minimumwidth'] 6051edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fill = spec['fill'] 6052edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep padding = fill*(minimumwidth - len(sign) - len(body)) 6053edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6054edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep align = spec['align'] 6055edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if align == '<': 6056edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result = sign + body + padding 6057edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif align == '>': 6058edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result = padding + sign + body 6059edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif align == '=': 6060edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result = sign + padding + body 6061edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif align == '^': 6062edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep half = len(padding)//2 6063edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result = padding[:half] + sign + body + padding[half:] 6064edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 6065edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError('Unrecognised alignment field') 6066edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6067edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # make sure that result is unicode if necessary 6068edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if spec['unicode']: 6069edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result = unicode(result) 6070edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6071edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return result 6072edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6073edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _group_lengths(grouping): 6074edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Convert a localeconv-style grouping into a (possibly infinite) 6075edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep iterable of integers representing group lengths. 6076edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6077edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 6078edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # The result from localeconv()['grouping'], and the input to this 6079edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # function, should be a list of integers in one of the 6080edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # following three forms: 6081edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 6082edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # (1) an empty list, or 6083edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # (2) nonempty list of positive integers + [0] 6084edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # (3) list of positive integers + [locale.CHAR_MAX], or 6085edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6086edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep from itertools import chain, repeat 6087edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not grouping: 6088edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return [] 6089edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif grouping[-1] == 0 and len(grouping) >= 2: 6090edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return chain(grouping[:-1], repeat(grouping[-2])) 6091edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif grouping[-1] == _locale.CHAR_MAX: 6092edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return grouping[:-1] 6093edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 6094edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError('unrecognised format for grouping') 6095edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6096edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _insert_thousands_sep(digits, spec, min_width=1): 6097edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Insert thousands separators into a digit string. 6098edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6099edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep spec is a dictionary whose keys should include 'thousands_sep' and 6100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'grouping'; typically it's the result of parsing the format 6101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep specifier using _parse_format_specifier. 6102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep The min_width keyword argument gives the minimum length of the 6104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result, which will be padded on the left with zeros if necessary. 6105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep If necessary, the zero padding adds an extra '0' on the left to 6107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep avoid a leading thousands separator. For example, inserting 6108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep commas every three digits in '123456', with min_width=8, gives 6109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '0,123,456', even though that has length 9. 6110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 6112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sep = spec['thousands_sep'] 6114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep grouping = spec['grouping'] 6115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep groups = [] 6117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for l in _group_lengths(grouping): 6118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if l <= 0: 6119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError("group length should be positive") 6120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # max(..., 1) forces at least 1 digit to the left of a separator 6121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep l = min(max(len(digits), min_width, 1), l) 6122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep groups.append('0'*(l - len(digits)) + digits[-l:]) 6123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep digits = digits[:-l] 6124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep min_width -= l 6125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not digits and min_width <= 0: 6126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep break 6127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep min_width -= len(sep) 6128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 6129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep l = max(len(digits), min_width, 1) 6130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep groups.append('0'*(l - len(digits)) + digits[-l:]) 6131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return sep.join(reversed(groups)) 6132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _format_sign(is_negative, spec): 6134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Determine sign character.""" 6135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if is_negative: 6137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return '-' 6138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif spec['sign'] in ' +': 6139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return spec['sign'] 6140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 6141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return '' 6142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _format_number(is_negative, intpart, fracpart, exp, spec): 6144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Format a number, given the following data: 6145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep is_negative: true if the number is negative, else false 6147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep intpart: string of digits that must appear before the decimal point 6148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fracpart: string of digits that must come after the point 6149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exp: exponent, as an integer 6150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep spec: dictionary resulting from parsing the format specifier 6151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep This function uses the information in spec to: 6153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep insert separators (decimal separator and thousands separators) 6154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format the sign 6155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep format the exponent 6156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep add trailing '%' for the '%' type 6157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep zero-pad if necessary 6158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fill and align if necessary 6159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 6160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = _format_sign(is_negative, spec) 6162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if fracpart: 6164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fracpart = spec['decimal_point'] + fracpart 6165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if exp != 0 or spec['type'] in 'eE': 6167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep echar = {'E': 'E', 'e': 'e', 'G': 'E', 'g': 'e'}[spec['type']] 6168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fracpart += "{0}{1:+}".format(echar, exp) 6169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if spec['type'] == '%': 6170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fracpart += '%' 6171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if spec['zeropad']: 6173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep min_width = spec['minimumwidth'] - len(fracpart) - len(sign) 6174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 6175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep min_width = 0 6176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep intpart = _insert_thousands_sep(intpart, spec, min_width) 6177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return _format_align(sign, intpart+fracpart, spec) 6179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### Useful Constants (internal use only) ################################ 6182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Reusable defaults 6184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_Infinity = Decimal('Inf') 6185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_NegativeInfinity = Decimal('-Inf') 6186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_NaN = Decimal('NaN') 6187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_Zero = Decimal(0) 6188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_One = Decimal(1) 6189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_NegativeOne = Decimal(-1) 6190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# _SignedInfinity[sign] is infinity w/ that sign 6192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_SignedInfinity = (_Infinity, _NegativeInfinity) 6193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepif __name__ == '__main__': 6197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep import doctest, sys 6198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep doctest.testmod(sys.modules[__name__]) 6199