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