10c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Copyright (c) 2004 Python Software Foundation. 20c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# All rights reserved. 30c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 40c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Written by Eric Price <eprice at tjhsst.edu> 50c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# and Facundo Batista <facundo at taniquetil.com.ar> 60c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# and Raymond Hettinger <python at rcn.com> 70c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# and Aahz <aahz at pobox.com> 80c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# and Tim Peters 90c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# This module is currently Py2.3 compatible and should be kept that way 110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# unless a major compelling advantage arises. IOW, 2.3 compatibility is 120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# strongly preferred, but not guaranteed. 130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Also, this module should be kept in sync with the latest updates of 150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# the IBM specification as it evolves. Those updates will be treated 160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# as bug fixes (deviation from the spec is a compatibility, usability 170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# bug) and will be backported. At this point the spec is stabilizing 180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# and the updates are becoming fewer, smaller, and less significant. 190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiThis is a Py2.3 implementation of decimal floating point arithmetic based on 220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yithe General Decimal Arithmetic Specification: 230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi http://speleotrove.com/decimal/decarith.html 250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiand IEEE standard 854-1987: 270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html 290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDecimal floating point has finite precision with arbitrarily large bounds. 310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiThe purpose of this module is to support arithmetic using familiar 330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi"schoolhouse" rules and to avoid some of the tricky representation 340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiissues associated with binary floating point. The package is especially 350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiuseful for financial applications or for contexts where users have 360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiexpectations that are at odds with binary floating point (for instance, 370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiin binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead 380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiof the expected Decimal('0.00') returned by decimal floating point). 390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiHere are some examples of using the decimal module: 410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> from decimal import * 430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> setcontext(ExtendedContext) 440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> Decimal(0) 450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDecimal('0') 460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> Decimal('1') 470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDecimal('1') 480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> Decimal('-.0123') 490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDecimal('-0.0123') 500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> Decimal(123456) 510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDecimal('123456') 520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> Decimal('123.45e12345678901234567890') 530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDecimal('1.2345E+12345678901234567892') 540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> Decimal('1.33') + Decimal('1.27') 550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDecimal('2.60') 560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> Decimal('12.34') + Decimal('3.87') - Decimal('18.41') 570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDecimal('-2.20') 580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> dig = Decimal(1) 590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print dig / Decimal(3) 600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi0.333333333 610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> getcontext().prec = 18 620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print dig / Decimal(3) 630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi0.333333333333333333 640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print dig.sqrt() 650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi1 660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print Decimal(3).sqrt() 670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi1.73205080756887729 680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print Decimal(3) ** 123 690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi4.85192780976896427E+58 700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> inf = Decimal(1) / Decimal(0) 710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print inf 720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiInfinity 730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> neginf = Decimal(-1) / Decimal(0) 740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print neginf 750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi-Infinity 760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print neginf + inf 770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiNaN 780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print neginf * inf 790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi-Infinity 800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print dig / 0 810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiInfinity 820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> getcontext().traps[DivisionByZero] = 1 830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print dig / 0 840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTraceback (most recent call last): 850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ... 860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ... 870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ... 880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDivisionByZero: x / 0 890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> c = Context() 900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> c.traps[InvalidOperation] = 0 910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print c.flags[InvalidOperation] 920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi0 930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> c.divide(Decimal(0), Decimal(0)) 940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDecimal('NaN') 950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> c.traps[InvalidOperation] = 1 960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print c.flags[InvalidOperation] 970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi1 980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> c.flags[InvalidOperation] = 0 990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print c.flags[InvalidOperation] 1000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi0 1010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print c.divide(Decimal(0), Decimal(0)) 1020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTraceback (most recent call last): 1030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ... 1040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ... 1050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ... 1060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiInvalidOperation: 0 / 0 1070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print c.flags[InvalidOperation] 1080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi1 1090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> c.flags[InvalidOperation] = 0 1100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> c.traps[InvalidOperation] = 0 1110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print c.divide(Decimal(0), Decimal(0)) 1120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiNaN 1130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> print c.flags[InvalidOperation] 1140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi1 1150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>>> 1160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 1170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi__all__ = [ 1190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Two major classes 1200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'Decimal', 'Context', 1210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Contexts 1230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'DefaultContext', 'BasicContext', 'ExtendedContext', 1240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Exceptions 1260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero', 1270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow', 1280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Constants for use in setting up contexts 1300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING', 1310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 'ROUND_05UP', 1320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Functions for manipulating contexts 1340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'setcontext', 'getcontext', 'localcontext' 1350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi] 1360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi__version__ = '1.70' # Highest version of the spec this complies with 1380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport copy as _copy 1400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport math as _math 1410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport numbers as _numbers 1420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yitry: 1440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi from collections import namedtuple as _namedtuple 1450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent') 1460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiexcept ImportError: 1470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi DecimalTuple = lambda *args: args 1480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Rounding 1500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiROUND_DOWN = 'ROUND_DOWN' 1510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiROUND_HALF_UP = 'ROUND_HALF_UP' 1520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiROUND_HALF_EVEN = 'ROUND_HALF_EVEN' 1530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiROUND_CEILING = 'ROUND_CEILING' 1540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiROUND_FLOOR = 'ROUND_FLOOR' 1550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiROUND_UP = 'ROUND_UP' 1560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiROUND_HALF_DOWN = 'ROUND_HALF_DOWN' 1570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiROUND_05UP = 'ROUND_05UP' 1580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Errors 1600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass DecimalException(ArithmeticError): 1620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Base exception class. 1630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Used exceptions derive from this. 1650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If an exception derives from another exception besides this (such as 1660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Underflow (Inexact, Rounded, Subnormal) that indicates that it is only 1670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi called if the others are present. This isn't actually used for 1680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi anything, though. 1690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi handle -- Called when context._raise_error is called and the 1710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi trap_enabler is not set. First argument is self, second is the 1720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context. More arguments can be given, those being after 1730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the explanation in _raise_error (For example, 1740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(NewError, '(-x)!', self._sign) would 1750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi call NewError().handle(context, self._sign).) 1760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi To define a new exception, it should be sufficient to have it derive 1780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi from DecimalException. 1790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 1800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def handle(self, context, *args): 1810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pass 1820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Clamped(DecimalException): 1850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Exponent of a 0 changed to fit bounds. 1860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This occurs and signals clamped if the exponent of a result has been 1880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi altered in order to fit the constraints of a specific concrete 1890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi representation. This may occur when the exponent of a zero result would 1900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi be outside the bounds of a representation, or when a large normal 1910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi number would have an encoded exponent that cannot be represented. In 1920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi this latter case, the exponent is reduced to fit and the corresponding 1930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi number of zero digits are appended to the coefficient ("fold-down"). 1940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 1950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass InvalidOperation(DecimalException): 1970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """An invalid operation was performed. 1980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Various bad things cause this: 2000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Something creates a signaling NaN 2020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi -INF + INF 2030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 0 * (+-)INF 2040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (+-)INF / (+-)INF 2050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi x % 0 2060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (+-)INF % x 2070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi x._rescale( non-integer ) 2080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sqrt(-x) , x > 0 2090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 0 ** 0 2100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi x ** (non-integer) 2110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi x ** (+-)INF 2120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi An operand is invalid 2130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The result of the operation after these is a quiet positive NaN, 2150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except when the cause is a signaling NaN, in which case the result is 2160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi also a quiet NaN, but with the original sign, and an optional 2170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi diagnostic information. 2180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 2190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def handle(self, context, *args): 2200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if args: 2210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(args[0]._sign, args[0]._int, 'n', True) 2220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans._fix_nan(context) 2230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NaN 2240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass ConversionSyntax(InvalidOperation): 2260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Trying to convert badly formed string. 2270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This occurs and signals invalid-operation if an string is being 2290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi converted to a number and it does not conform to the numeric string 2300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi syntax. The result is [0,qNaN]. 2310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 2320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def handle(self, context, *args): 2330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NaN 2340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass DivisionByZero(DecimalException, ZeroDivisionError): 2360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Division by 0. 2370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This occurs and signals division-by-zero if division of a finite number 2390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi by zero was attempted (during a divide-integer or divide operation, or a 2400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi power operation with negative right-hand operand), and the dividend was 2410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi not zero. 2420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The result of the operation is [sign,inf], where sign is the exclusive 2440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi or of the signs of the operands for divide, or is 1 for an odd power of 2450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi -0, for power. 2460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 2470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def handle(self, context, sign, *args): 2490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _SignedInfinity[sign] 2500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass DivisionImpossible(InvalidOperation): 2520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Cannot perform the division adequately. 2530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This occurs and signals invalid-operation if the integer result of a 2550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi divide-integer or remainder operation had too many digits (would be 2560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi longer than precision). The result is [0,qNaN]. 2570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 2580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def handle(self, context, *args): 2600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NaN 2610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass DivisionUndefined(InvalidOperation, ZeroDivisionError): 2630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Undefined result of division. 2640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This occurs and signals invalid-operation if division by zero was 2660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attempted (during a divide-integer, divide, or remainder operation), and 2670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the dividend is also zero. The result is [0,qNaN]. 2680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 2690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def handle(self, context, *args): 2710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NaN 2720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Inexact(DecimalException): 2740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Had to round, losing information. 2750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This occurs and signals inexact whenever the result of an operation is 2770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi not exact (that is, it needed to be rounded and any discarded digits 2780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi were non-zero), or if an overflow or underflow condition occurs. The 2790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result in all cases is unchanged. 2800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The inexact signal may be tested (or trapped) to determine if a given 2820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operation (or sequence of operations) was inexact. 2830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 2840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass InvalidContext(InvalidOperation): 2860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Invalid context. Unknown rounding, for example. 2870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This occurs and signals invalid-operation if an invalid context was 2890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi detected during an operation. This can occur if contexts are not checked 2900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi on creation and either the precision exceeds the capability of the 2910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi underlying concrete representation or an unknown or unsupported rounding 2920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi was specified. These aspects of the context need only be checked when 2930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the values are required to be used. The result is [0,qNaN]. 2940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 2950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def handle(self, context, *args): 2970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NaN 2980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Rounded(DecimalException): 3000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Number got rounded (not necessarily changed during rounding). 3010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This occurs and signals rounded whenever the result of an operation is 3030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rounded (that is, some zero or non-zero digits were discarded from the 3040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coefficient), or if an overflow or underflow condition occurs. The 3050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result in all cases is unchanged. 3060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The rounded signal may be tested (or trapped) to determine if a given 3080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operation (or sequence of operations) caused a loss of precision. 3090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 3100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Subnormal(DecimalException): 3120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Exponent < Emin before rounding. 3130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This occurs and signals subnormal whenever the result of a conversion or 3150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operation is subnormal (that is, its adjusted exponent is less than 3160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Emin, before any rounding). The result in all cases is unchanged. 3170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The subnormal signal may be tested (or trapped) to determine if a given 3190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi or operation (or sequence of operations) yielded a subnormal result. 3200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 3210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Overflow(Inexact, Rounded): 3230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Numerical overflow. 3240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This occurs and signals overflow if the adjusted exponent of a result 3260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (from a conversion or from an operation that is not an attempt to divide 3270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi by zero), after rounding, would be greater than the largest value that 3280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi can be handled by the implementation (the value Emax). 3290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The result depends on the rounding mode: 3310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi For round-half-up and round-half-even (and for round-half-down and 3330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi round-up, if implemented), the result of the operation is [sign,inf], 3340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi where sign is the sign of the intermediate result. For round-down, the 3350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result is the largest finite number that can be represented in the 3360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi current precision, with the sign of the intermediate result. For 3370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi round-ceiling, the result is the same as for round-down if the sign of 3380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the intermediate result is 1, or is [0,inf] otherwise. For round-floor, 3390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the result is the same as for round-down if the sign of the intermediate 3400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded 3410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi will also be raised. 3420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 3430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def handle(self, context, sign, *args): 3450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN, 3460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ROUND_HALF_DOWN, ROUND_UP): 3470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _SignedInfinity[sign] 3480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if sign == 0: 3490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context.rounding == ROUND_CEILING: 3500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _SignedInfinity[sign] 3510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(sign, '9'*context.prec, 3520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context.Emax-context.prec+1) 3530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if sign == 1: 3540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context.rounding == ROUND_FLOOR: 3550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _SignedInfinity[sign] 3560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(sign, '9'*context.prec, 3570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context.Emax-context.prec+1) 3580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Underflow(Inexact, Rounded, Subnormal): 3610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Numerical underflow with result rounded to 0. 3620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This occurs and signals underflow if a result is inexact and the 3640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi adjusted exponent of the result would be smaller (more negative) than 3650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the smallest value that can be handled by the implementation (the value 3660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Emin). That is, the result is both inexact and subnormal. 3670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The result after an underflow will be a subnormal number rounded, if 3690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi necessary, so that its exponent is not less than Etiny. This may result 3700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi in 0 with the sign of the intermediate result and an exponent of Etiny. 3710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi In all cases, Inexact, Rounded, and Subnormal will also be raised. 3730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 3740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# List of public traps and flags 3760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded, 3770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Underflow, InvalidOperation, Subnormal] 3780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Map conditions (per the spec) to signals 3800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_condition_map = {ConversionSyntax:InvalidOperation, 3810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi DivisionImpossible:InvalidOperation, 3820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi DivisionUndefined:InvalidOperation, 3830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi InvalidContext:InvalidOperation} 3840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##### Context Functions ################################################## 3860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# The getcontext() and setcontext() function manage access to a thread-local 3880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# current context. Py2.4 offers direct support for thread locals. If that 3890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# is not available, use threading.currentThread() which is slower but will 3900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# work for older Pythons. If threads are not part of the build, create a 3910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# mock threading object with threading.local() returning the module namespace. 3920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yitry: 3940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi import threading 3950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiexcept ImportError: 3960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Python was compiled without threads; create a mock object instead 3970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi import sys 3980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi class MockThreading(object): 3990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def local(self, sys=sys): 4000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return sys.modules[__name__] 4010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi threading = MockThreading() 4020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del sys, MockThreading 4030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yitry: 4050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi threading.local 4060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiexcept AttributeError: 4080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # To fix reloading, force it to create a new context 4100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Old contexts have different exceptions in their dicts, making problems. 4110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if hasattr(threading.currentThread(), '__decimal_context__'): 4120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del threading.currentThread().__decimal_context__ 4130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setcontext(context): 4150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Set this thread's context to context.""" 4160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context in (DefaultContext, BasicContext, ExtendedContext): 4170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = context.copy() 4180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context.clear_flags() 4190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi threading.currentThread().__decimal_context__ = context 4200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getcontext(): 4220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns this thread's context. 4230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If this thread does not yet have a context, returns 4250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a new context and sets this thread's context. 4260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi New contexts are copies of DefaultContext. 4270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 4280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 4290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return threading.currentThread().__decimal_context__ 4300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except AttributeError: 4310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = Context() 4320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi threading.currentThread().__decimal_context__ = context 4330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context 4340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yielse: 4360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi local = threading.local() 4380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if hasattr(local, '__decimal_context__'): 4390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del local.__decimal_context__ 4400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getcontext(_local=local): 4420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns this thread's context. 4430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If this thread does not yet have a context, returns 4450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a new context and sets this thread's context. 4460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi New contexts are copies of DefaultContext. 4470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 4480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 4490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _local.__decimal_context__ 4500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except AttributeError: 4510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = Context() 4520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _local.__decimal_context__ = context 4530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context 4540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setcontext(context, _local=local): 4560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Set this thread's context to context.""" 4570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context in (DefaultContext, BasicContext, ExtendedContext): 4580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = context.copy() 4590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context.clear_flags() 4600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _local.__decimal_context__ = context 4610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del threading, local # Don't contaminate the namespace 4630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef localcontext(ctx=None): 4650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return a context manager for a copy of the supplied context 4660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Uses a copy of the current context if no context is specified 4680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The returned context manager creates a local decimal context 4690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi in a with statement: 4700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def sin(x): 4710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi with localcontext() as ctx: 4720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ctx.prec += 2 4730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Rest of sin calculation algorithm 4740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # uses a precision 2 greater than normal 4750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return +s # Convert result to normal precision 4760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def sin(x): 4780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi with localcontext(ExtendedContext): 4790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Rest of sin calculation algorithm 4800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # uses the Extended Context from the 4810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # General Decimal Arithmetic Specification 4820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return +s # Convert result to normal context 4830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> setcontext(DefaultContext) 4850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> print getcontext().prec 4860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28 4870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> with localcontext(): 4880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ... ctx = getcontext() 4890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ... ctx.prec += 2 4900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ... print ctx.prec 4910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ... 4920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30 4930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> with localcontext(ExtendedContext): 4940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ... print getcontext().prec 4950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ... 4960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9 4970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> print getcontext().prec 4980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28 4990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 5000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ctx is None: ctx = getcontext() 5010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _ContextManager(ctx) 5020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##### Decimal class ####################################################### 5050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Decimal(object): 5070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Floating point class for decimal arithmetic.""" 5080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __slots__ = ('_exp','_int','_sign', '_is_special') 5100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Generally, the value of the Decimal instance is given by 5110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # (-1)**_sign * _int * 10**_exp 5120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Special values are signified by _is_special == True 5130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # We're immutable, so use __new__ not __init__ 5150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __new__(cls, value="0", context=None): 5160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Create a decimal point instance. 5170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> Decimal('3.14') # string input 5190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3.14') 5200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> Decimal((0, (3, 1, 4), -2)) # tuple (sign, digit_tuple, exponent) 5210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3.14') 5220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> Decimal(314) # int or long 5230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('314') 5240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> Decimal(Decimal(314)) # another decimal instance 5250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('314') 5260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> Decimal(' 3.14 \\n') # leading and trailing whitespace okay 5270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3.14') 5280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 5290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Note that the coefficient, self._int, is actually stored as 5310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # a string rather than as a tuple of digits. This speeds up 5320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # the "digits to integer" and "integer to digits" conversions 5330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # that are used in almost every arithmetic operation on 5340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Decimals. This is an internal detail: the as_tuple function 5350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # and the Decimal constructor still deal with tuples of 5360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # digits. 5370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self = object.__new__(cls) 5390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # From a string 5410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # REs insist on real strings, so we can too. 5420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(value, basestring): 5430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = _parser(value.strip()) 5440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if m is None: 5450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 5460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 5470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(ConversionSyntax, 5480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "Invalid literal for Decimal: %r" % value) 5490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if m.group('sign') == "-": 5510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._sign = 1 5520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 5530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._sign = 0 5540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi intpart = m.group('int') 5550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if intpart is not None: 5560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # finite number 5570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fracpart = m.group('frac') or '' 5580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = int(m.group('exp') or '0') 5590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._int = str(int(intpart+fracpart)) 5600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._exp = exp - len(fracpart) 5610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._is_special = False 5620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 5630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi diag = m.group('diag') 5640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if diag is not None: 5650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # NaN 5660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._int = str(int(diag or '0')).lstrip('0') 5670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if m.group('signal'): 5680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._exp = 'N' 5690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 5700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._exp = 'n' 5710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 5720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # infinity 5730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._int = '0' 5740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._exp = 'F' 5750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._is_special = True 5760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self 5770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # From an integer 5790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(value, (int,long)): 5800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if value >= 0: 5810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._sign = 0 5820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 5830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._sign = 1 5840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._exp = 0 5850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._int = str(abs(value)) 5860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._is_special = False 5870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self 5880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # From another decimal 5900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(value, Decimal): 5910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._exp = value._exp 5920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._sign = value._sign 5930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._int = value._int 5940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._is_special = value._is_special 5950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self 5960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # From an internal working value 5980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(value, _WorkRep): 5990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._sign = value.sign 6000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._int = str(value.int) 6010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._exp = int(value.exp) 6020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._is_special = False 6030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self 6040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # tuple/list conversion (possibly from as_tuple()) 6060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(value, (list,tuple)): 6070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if len(value) != 3: 6080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError('Invalid tuple size in creation of Decimal ' 6090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'from list or tuple. The list or tuple ' 6100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'should have exactly three elements.') 6110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # process sign. The isinstance test rejects floats 6120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not (isinstance(value[0], (int, long)) and value[0] in (0,1)): 6130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("Invalid sign. The first value in the tuple " 6140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "should be an integer; either 0 for a " 6150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "positive number or 1 for a negative number.") 6160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._sign = value[0] 6170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if value[2] == 'F': 6180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # infinity: value[1] is ignored 6190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._int = '0' 6200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._exp = value[2] 6210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._is_special = True 6220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 6230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # process and validate the digits in value[1] 6240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi digits = [] 6250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for digit in value[1]: 6260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(digit, (int, long)) and 0 <= digit <= 9: 6270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # skip leading zeros 6280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if digits or digit != 0: 6290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi digits.append(digit) 6300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 6310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("The second value in the tuple must " 6320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "be composed of integers in the range " 6330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "0 through 9.") 6340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if value[2] in ('n', 'N'): 6350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # NaN: digits form the diagnostic 6360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._int = ''.join(map(str, digits)) 6370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._exp = value[2] 6380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._is_special = True 6390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif isinstance(value[2], (int, long)): 6400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # finite number: digits give the coefficient 6410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._int = ''.join(map(str, digits or [0])) 6420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._exp = value[2] 6430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._is_special = False 6440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 6450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("The third value in the tuple must " 6460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "be an integer, or one of the " 6470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "strings 'F', 'n', 'N'.") 6480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self 6490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(value, float): 6510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi value = Decimal.from_float(value) 6520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._exp = value._exp 6530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._sign = value._sign 6540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._int = value._int 6550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._is_special = value._is_special 6560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self 6570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise TypeError("Cannot convert %r to Decimal" % value) 6590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # @classmethod, but @decorator is not valid Python 2.3 syntax, so 6610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # don't use it (see notes on Py2.3 compatibility at top of file) 6620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def from_float(cls, f): 6630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Converts a float to a decimal number, exactly. 6640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Note that Decimal.from_float(0.1) is not the same as Decimal('0.1'). 6660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Since 0.1 is not exactly representable in binary floating point, the 6670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi value is stored as the nearest representable value which is 6680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 0x1.999999999999ap-4. The exact equivalent of the value in decimal 6690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi is 0.1000000000000000055511151231257827021181583404541015625. 6700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> Decimal.from_float(0.1) 6720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.1000000000000000055511151231257827021181583404541015625') 6730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> Decimal.from_float(float('nan')) 6740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('NaN') 6750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> Decimal.from_float(float('inf')) 6760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('Infinity') 6770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> Decimal.from_float(-float('inf')) 6780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-Infinity') 6790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> Decimal.from_float(-0.0) 6800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-0') 6810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 6830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(f, (int, long)): # handle integer inputs 6840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return cls(f) 6850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if _math.isinf(f) or _math.isnan(f): # raises TypeError if not a float 6860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return cls(repr(f)) 6870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if _math.copysign(1.0, f) == 1.0: 6880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = 0 6890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 6900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = 1 6910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n, d = abs(f).as_integer_ratio() 6920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi k = d.bit_length() - 1 6930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result = _dec_from_triple(sign, str(n*5**k), -k) 6940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if cls is Decimal: 6950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return result 6960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 6970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return cls(result) 6980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi from_float = classmethod(from_float) 6990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _isnan(self): 7010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns whether the number is not actually one. 7020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 0 if a number 7040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1 if NaN 7050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2 if sNaN 7060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 7070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special: 7080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = self._exp 7090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if exp == 'n': 7100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 1 7110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif exp == 'N': 7120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 2 7130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 0 7140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _isinfinity(self): 7160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns whether the number is infinite 7170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 0 if finite or not a number 7190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1 if +INF 7200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi -1 if -INF 7210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 7220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._exp == 'F': 7230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign: 7240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return -1 7250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 1 7260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 0 7270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _check_nans(self, other=None, context=None): 7290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns whether the number is not actually one. 7300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self, other are sNaN, signal 7320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self, other are NaN return nan 7330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 0 7340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Done before operations. 7360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 7370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self_is_nan = self._isnan() 7390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is None: 7400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other_is_nan = False 7410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 7420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other_is_nan = other._isnan() 7430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_is_nan or other_is_nan: 7450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 7460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 7470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_is_nan == 2: 7490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 'sNaN', 7500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self) 7510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other_is_nan == 2: 7520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 'sNaN', 7530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other) 7540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_is_nan: 7550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._fix_nan(context) 7560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other._fix_nan(context) 7580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 0 7590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _compare_check_nans(self, other, context): 7610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Version of _check_nans used for the signaling comparisons 7620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi compare_signal, __le__, __lt__, __ge__, __gt__. 7630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Signal InvalidOperation if either self or other is a (quiet 7650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi or signaling) NaN. Signaling NaNs take precedence over quiet 7660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi NaNs. 7670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Return 0 if neither operand is a NaN. 7690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 7710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 7720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 7730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or other._is_special: 7750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.is_snan(): 7760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 7770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'comparison involving sNaN', 7780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self) 7790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif other.is_snan(): 7800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 7810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'comparison involving sNaN', 7820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other) 7830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif self.is_qnan(): 7840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 7850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'comparison involving NaN', 7860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self) 7870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif other.is_qnan(): 7880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 7890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'comparison involving NaN', 7900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other) 7910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 0 7920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __nonzero__(self): 7940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if self is nonzero; otherwise return False. 7950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi NaNs and infinities are considered nonzero. 7970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 7980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._is_special or self._int != '0' 7990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _cmp(self, other): 8010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compare the two non-NaN decimal instances self and other. 8020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Returns -1 if self < other, 0 if self == other and 1 8040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self > other. This routine is for internal use only.""" 8050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or other._is_special: 8070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self_inf = self._isinfinity() 8080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other_inf = other._isinfinity() 8090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_inf == other_inf: 8100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 0 8110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif self_inf < other_inf: 8120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return -1 8130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 8140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 1 8150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # check for zeros; Decimal('0') == Decimal('-0') 8170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 8180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not other: 8190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 0 8200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 8210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return -((-1)**other._sign) 8220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not other: 8230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return (-1)**self._sign 8240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # If different signs, neg one is less 8260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._sign < self._sign: 8270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return -1 8280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign < other._sign: 8290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 1 8300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self_adjusted = self.adjusted() 8320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other_adjusted = other.adjusted() 8330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_adjusted == other_adjusted: 8340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self_padded = self._int + '0'*(self._exp - other._exp) 8350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other_padded = other._int + '0'*(other._exp - self._exp) 8360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_padded == other_padded: 8370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 0 8380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif self_padded < other_padded: 8390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return -(-1)**self._sign 8400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 8410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return (-1)**self._sign 8420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif self_adjusted > other_adjusted: 8430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return (-1)**self._sign 8440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: # self_adjusted < other_adjusted 8450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return -((-1)**self._sign) 8460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Note: The Decimal standard doesn't cover rich comparisons for 8480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Decimals. In particular, the specification is silent on the 8490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # subject of what should happen for a comparison involving a NaN. 8500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # We take the following approach: 8510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 8520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # == comparisons involving a quiet NaN always return False 8530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # != comparisons involving a quiet NaN always return True 8540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # == or != comparisons involving a signaling NaN signal 8550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # InvalidOperation, and return False or True as above if the 8560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # InvalidOperation is not trapped. 8570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # <, >, <= and >= comparisons involving a (quiet or signaling) 8580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # NaN signal InvalidOperation, and return False if the 8590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # InvalidOperation is not trapped. 8600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 8610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # This behavior is designed to conform as closely as possible to 8620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # that specified by IEEE 754. 8630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __eq__(self, other, context=None): 8650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, allow_float=True) 8660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 8670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 8680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._check_nans(other, context): 8690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 8700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._cmp(other) == 0 8710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __ne__(self, other, context=None): 8730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, allow_float=True) 8740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 8750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 8760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._check_nans(other, context): 8770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return True 8780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._cmp(other) != 0 8790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __lt__(self, other, context=None): 8810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, allow_float=True) 8820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 8830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 8840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._compare_check_nans(other, context) 8850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 8860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 8870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._cmp(other) < 0 8880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __le__(self, other, context=None): 8900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, allow_float=True) 8910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 8920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 8930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._compare_check_nans(other, context) 8940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 8950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 8960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._cmp(other) <= 0 8970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __gt__(self, other, context=None): 8990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, allow_float=True) 9000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 9010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 9020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._compare_check_nans(other, context) 9030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 9040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 9050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._cmp(other) > 0 9060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __ge__(self, other, context=None): 9080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, allow_float=True) 9090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 9100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 9110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._compare_check_nans(other, context) 9120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 9130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 9140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._cmp(other) >= 0 9150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def compare(self, other, context=None): 9170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compares one to another. 9180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi -1 => a < b 9200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 0 => a = b 9210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1 => a > b 9220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi NaN => one is NaN 9230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Like __cmp__, but returns Decimal instances. 9240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 9250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 9260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Compare(NaN, NaN) = NaN 9280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if (self._is_special or other and other._is_special): 9290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(other, context) 9300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 9310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 9320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self._cmp(other)) 9340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __hash__(self): 9360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """x.__hash__() <==> hash(x)""" 9370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Decimal integers must hash the same as the ints 9380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 9390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # The hash of a nonspecial noninteger Decimal must depend only 9400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # on the value of that Decimal, and not on its representation. 9410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # For example: hash(Decimal('100E-1')) == hash(Decimal('10')). 9420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Equality comparisons involving signaling nans can raise an 9440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exception; since equality checks are implicitly and 9450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # unpredictably used when checking set and dict membership, we 9460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # prevent signaling nans from being used as set elements or 9470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # dict keys by making __hash__ raise an exception. 9480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special: 9490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.is_snan(): 9500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise TypeError('Cannot hash a signaling NaN value.') 9510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif self.is_nan(): 9520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 0 to match hash(float('nan')) 9530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 0 9540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 9550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # values chosen to match hash(float('inf')) and 9560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # hash(float('-inf')). 9570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign: 9580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return -271828 9590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 9600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 314159 9610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # In Python 2.7, we're allowing comparisons (but not 9630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # arithmetic operations) between floats and Decimals; so if 9640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # a Decimal instance is exactly representable as a float then 9650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # its hash should match that of the float. 9660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self_as_float = float(self) 9670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if Decimal.from_float(self_as_float) == self: 9680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return hash(self_as_float) 9690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinteger(): 9710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op = _WorkRep(self.to_integral_value()) 9720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # to make computation feasible for Decimals with large 9730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exponent, we use the fact that hash(n) == hash(m) for 9740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # any two nonzero integers n and m such that (i) n and m 9750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # have the same sign, and (ii) n is congruent to m modulo 9760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 2**64-1. So we can replace hash((-1)**s*c*10**e) with 9770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # hash((-1)**s*c*pow(10, e, 2**64-1). 9780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return hash((-1)**op.sign*op.int*pow(10, op.exp, 2**64-1)) 9790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # The value of a nonzero nonspecial Decimal instance is 9800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # faithfully represented by the triple consisting of its sign, 9810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # its adjusted exponent, and its coefficient with trailing 9820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # zeros removed. 9830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return hash((self._sign, 9840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._exp+len(self._int), 9850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._int.rstrip('0'))) 9860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def as_tuple(self): 9880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Represents the number as a triple tuple. 9890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi To show the internals exactly as they are. 9910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 9920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return DecimalTuple(self._sign, tuple(map(int, self._int)), self._exp) 9930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __repr__(self): 9950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Represents the number as an instance of Decimal.""" 9960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Invariant: eval(repr(d)) == d 9970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "Decimal('%s')" % str(self) 9980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __str__(self, eng=False, context=None): 10000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return string representation of the number in scientific notation. 10010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Captures all of the information in the underlying representation. 10030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 10040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = ['', '-'][self._sign] 10060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special: 10070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._exp == 'F': 10080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return sign + 'Infinity' 10090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif self._exp == 'n': 10100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return sign + 'NaN' + self._int 10110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: # self._exp == 'N' 10120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return sign + 'sNaN' + self._int 10130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # number of digits of self._int to left of decimal point 10150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi leftdigits = self._exp + len(self._int) 10160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # dotplace is number of digits of self._int to the left of the 10180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # decimal point in the mantissa of the output string (that is, 10190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # after adjusting the exponent) 10200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._exp <= 0 and leftdigits > -6: 10210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # no exponent required 10220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dotplace = leftdigits 10230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif not eng: 10240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # usual scientific notation: 1 digit on left of the point 10250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dotplace = 1 10260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif self._int == '0': 10270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # engineering notation, zero 10280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dotplace = (leftdigits + 1) % 3 - 1 10290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 10300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # engineering notation, nonzero 10310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dotplace = (leftdigits - 1) % 3 + 1 10320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if dotplace <= 0: 10340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi intpart = '0' 10350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fracpart = '.' + '0'*(-dotplace) + self._int 10360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif dotplace >= len(self._int): 10370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi intpart = self._int+'0'*(dotplace-len(self._int)) 10380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fracpart = '' 10390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 10400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi intpart = self._int[:dotplace] 10410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fracpart = '.' + self._int[dotplace:] 10420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if leftdigits == dotplace: 10430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = '' 10440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 10450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 10460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 10470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = ['e', 'E'][context.capitals] + "%+d" % (leftdigits-dotplace) 10480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return sign + intpart + fracpart + exp 10500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def to_eng_string(self, context=None): 10520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Convert to engineering-type string. 10530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Engineering notation has an exponent which is a multiple of 3, so there 10550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi are up to 3 digits left of the decimal place. 10560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Same rules for when in exponential and when as a value as in __str__. 10580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 10590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.__str__(eng=True, context=context) 10600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __neg__(self, context=None): 10620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns a copy with the sign switched. 10630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Rounds, if it has reason. 10650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 10660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special: 10670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(context=context) 10680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 10690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 10700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 10720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 10730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self and context.rounding != ROUND_FLOOR: 10750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # -Decimal('0') is Decimal('0'), not Decimal('-0'), except 10760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # in ROUND_FLOOR rounding mode. 10770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self.copy_abs() 10780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 10790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self.copy_negate() 10800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans._fix(context) 10820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __pos__(self, context=None): 10840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns a copy, unless it is a sNaN. 10850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Rounds the number (if more then precision digits) 10870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 10880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special: 10890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(context=context) 10900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 10910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 10920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 10940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 10950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self and context.rounding != ROUND_FLOOR: 10970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # + (-0) = 0, except in ROUND_FLOOR rounding mode. 10980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self.copy_abs() 10990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 11000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = Decimal(self) 11010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans._fix(context) 11030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __abs__(self, round=True, context=None): 11050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the absolute value of self. 11060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If the keyword argument 'round' is false, do not round. The 11080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi expression self.__abs__(round=False) is equivalent to 11090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.copy_abs(). 11100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 11110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not round: 11120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.copy_abs() 11130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special: 11150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(context=context) 11160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 11170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 11180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign: 11200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self.__neg__(context=context) 11210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 11220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self.__pos__(context=context) 11230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 11250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __add__(self, other, context=None): 11270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns self + other. 11280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi -INF + INF (or the reverse) cause InvalidOperation errors. 11300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 11310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other) 11320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 11330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 11340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 11360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 11370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or other._is_special: 11390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(other, context) 11400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 11410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 11420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity(): 11440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # If both INF, same sign => same as both, opposite => error. 11450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign != other._sign and other._isinfinity(): 11460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, '-INF + INF') 11470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 11480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._isinfinity(): 11490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(other) # Can't both be infinity here 11500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = min(self._exp, other._exp) 11520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi negativezero = 0 11530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context.rounding == ROUND_FLOOR and self._sign != other._sign: 11540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # If the answer is 0, the sign should be negative, in this case. 11550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi negativezero = 1 11560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self and not other: 11580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = min(self._sign, other._sign) 11590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if negativezero: 11600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = 1 11610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(sign, '0', exp) 11620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(context) 11630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 11640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 11650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = max(exp, other._exp - context.prec-1) 11660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = other._rescale(exp, context.rounding) 11670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(context) 11680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 11690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not other: 11700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = max(exp, self._exp - context.prec-1) 11710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._rescale(exp, context.rounding) 11720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(context) 11730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 11740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op1 = _WorkRep(self) 11760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op2 = _WorkRep(other) 11770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op1, op2 = _normalize(op1, op2, context.prec) 11780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result = _WorkRep() 11800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if op1.sign != op2.sign: 11810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Equal and opposite 11820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if op1.int == op2.int: 11830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(negativezero, '0', exp) 11840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(context) 11850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 11860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if op1.int < op2.int: 11870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op1, op2 = op2, op1 11880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # OK, now abs(op1) > abs(op2) 11890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if op1.sign == 1: 11900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result.sign = 1 11910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op1.sign, op2.sign = op2.sign, op1.sign 11920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 11930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result.sign = 0 11940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # So we know the sign, and op1 > 0. 11950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif op1.sign == 1: 11960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result.sign = 1 11970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op1.sign, op2.sign = (0, 0) 11980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 11990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result.sign = 0 12000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Now, op1 > abs(op2) > 0 12010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if op2.sign == 0: 12030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result.int = op1.int + op2.int 12040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 12050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result.int = op1.int - op2.int 12060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result.exp = op1.exp 12080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = Decimal(result) 12090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(context) 12100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 12110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __radd__ = __add__ 12130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __sub__(self, other, context=None): 12150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return self - other""" 12160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other) 12170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 12180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 12190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or other._is_special: 12210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(other, context=context) 12220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 12230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 12240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # self - other is computed as self + other.copy_negate() 12260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.__add__(other.copy_negate(), context=context) 12270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __rsub__(self, other, context=None): 12290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return other - self""" 12300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other) 12310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 12320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 12330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other.__sub__(self, context=context) 12350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __mul__(self, other, context=None): 12370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return self * other. 12380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (+-) INF * 0 (or its reverse) raise InvalidOperation. 12400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 12410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other) 12420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 12430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 12440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 12460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 12470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi resultsign = self._sign ^ other._sign 12490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or other._is_special: 12510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(other, context) 12520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 12530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 12540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity(): 12560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not other: 12570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, '(+-)INF * 0') 12580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _SignedInfinity[resultsign] 12590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._isinfinity(): 12610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 12620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, '0 * (+-)INF') 12630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _SignedInfinity[resultsign] 12640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi resultexp = self._exp + other._exp 12660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Special case for multiplying by zero 12680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self or not other: 12690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(resultsign, '0', resultexp) 12700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Fixing in case the exponent is out of bounds 12710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(context) 12720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 12730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Special case for multiplying by power of 10 12750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._int == '1': 12760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(resultsign, other._int, resultexp) 12770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(context) 12780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 12790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._int == '1': 12800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(resultsign, self._int, resultexp) 12810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(context) 12820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 12830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op1 = _WorkRep(self) 12850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op2 = _WorkRep(other) 12860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(resultsign, str(op1.int * op2.int), resultexp) 12880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(context) 12890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 12910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __rmul__ = __mul__ 12920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __truediv__(self, other, context=None): 12940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return self / other.""" 12950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other) 12960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 12970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return NotImplemented 12980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 13000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 13010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = self._sign ^ other._sign 13030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or other._is_special: 13050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(other, context) 13060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 13070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 13080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity() and other._isinfinity(): 13100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF') 13110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity(): 13130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _SignedInfinity[sign] 13140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._isinfinity(): 13160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Clamped, 'Division by infinity') 13170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(sign, '0', context.Etiny()) 13180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Special cases for zeroes 13200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not other: 13210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 13220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(DivisionUndefined, '0 / 0') 13230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(DivisionByZero, 'x / 0', sign) 13240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 13260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = self._exp - other._exp 13270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff = 0 13280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 13290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # OK, so neither = 0, INF or NaN 13300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi shift = len(other._int) - len(self._int) + context.prec + 1 13310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = self._exp - other._exp - shift 13320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op1 = _WorkRep(self) 13330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op2 = _WorkRep(other) 13340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if shift >= 0: 13350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff, remainder = divmod(op1.int * 10**shift, op2.int) 13360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 13370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff, remainder = divmod(op1.int, op2.int * 10**-shift) 13380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if remainder: 13390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # result is not exact; adjust to ensure correct rounding 13400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if coeff % 5 == 0: 13410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff += 1 13420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 13430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # result is exact; get as close to ideal exponent as possible 13440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ideal_exp = self._exp - other._exp 13450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while exp < ideal_exp and coeff % 10 == 0: 13460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff //= 10 13470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp += 1 13480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(sign, str(coeff), exp) 13500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans._fix(context) 13510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _divide(self, other, context): 13530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return (self // other, self % other), to context.prec precision. 13540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Assumes that neither self nor other is a NaN, that self is not 13560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi infinite and that other is nonzero. 13570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 13580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = self._sign ^ other._sign 13590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._isinfinity(): 13600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ideal_exp = self._exp 13610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 13620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ideal_exp = min(self._exp, other._exp) 13630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi expdiff = self.adjusted() - other.adjusted() 13650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self or other._isinfinity() or expdiff <= -2: 13660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return (_dec_from_triple(sign, '0', 0), 13670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._rescale(ideal_exp, context.rounding)) 13680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if expdiff <= context.prec: 13690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op1 = _WorkRep(self) 13700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op2 = _WorkRep(other) 13710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if op1.exp >= op2.exp: 13720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op1.int *= 10**(op1.exp - op2.exp) 13730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 13740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op2.int *= 10**(op2.exp - op1.exp) 13750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi q, r = divmod(op1.int, op2.int) 13760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if q < 10**context.prec: 13770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return (_dec_from_triple(sign, str(q), 0), 13780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _dec_from_triple(self._sign, str(r), ideal_exp)) 13790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Here the quotient is too large to be representable 13810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = context._raise_error(DivisionImpossible, 13820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'quotient too large in //, % or divmod') 13830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans, ans 13840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __rtruediv__(self, other, context=None): 13860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Swaps self/other and returns __truediv__.""" 13870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other) 13880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 13890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 13900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other.__truediv__(self, context=context) 13910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __div__ = __truediv__ 13930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __rdiv__ = __rtruediv__ 13940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __divmod__(self, other, context=None): 13960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 13970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Return (self // other, self % other) 13980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 13990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other) 14000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 14010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 14020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 14040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 14050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(other, context) 14070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 14080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return (ans, ans) 14090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = self._sign ^ other._sign 14110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity(): 14120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._isinfinity(): 14130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = context._raise_error(InvalidOperation, 'divmod(INF, INF)') 14140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans, ans 14150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 14160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return (_SignedInfinity[sign], 14170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(InvalidOperation, 'INF % x')) 14180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not other: 14200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 14210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = context._raise_error(DivisionUndefined, 'divmod(0, 0)') 14220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans, ans 14230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 14240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return (context._raise_error(DivisionByZero, 'x // 0', sign), 14250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(InvalidOperation, 'x % 0')) 14260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi quotient, remainder = self._divide(other, context) 14280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi remainder = remainder._fix(context) 14290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return quotient, remainder 14300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __rdivmod__(self, other, context=None): 14320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Swaps self/other and returns __divmod__.""" 14330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other) 14340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 14350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 14360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other.__divmod__(self, context=context) 14370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __mod__(self, other, context=None): 14390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 14400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self % other 14410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 14420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other) 14430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 14440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 14450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 14470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 14480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(other, context) 14500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 14510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 14520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity(): 14540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 'INF % x') 14550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif not other: 14560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self: 14570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 'x % 0') 14580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 14590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(DivisionUndefined, '0 % 0') 14600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi remainder = self._divide(other, context)[1] 14620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi remainder = remainder._fix(context) 14630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return remainder 14640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __rmod__(self, other, context=None): 14660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Swaps self/other and returns __mod__.""" 14670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other) 14680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 14690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 14700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other.__mod__(self, context=context) 14710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def remainder_near(self, other, context=None): 14730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 14740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Remainder nearest to 0- abs(remainder-near) <= other/2 14750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 14760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 14770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 14780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 14800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(other, context) 14820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 14830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 14840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # self == +/-infinity -> InvalidOperation 14860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity(): 14870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 14880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'remainder_near(infinity, x)') 14890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # other == 0 -> either InvalidOperation or DivisionUndefined 14910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not other: 14920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self: 14930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 14940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'remainder_near(x, 0)') 14950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 14960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(DivisionUndefined, 14970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'remainder_near(0, 0)') 14980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # other = +/-infinity -> remainder = self 15000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._isinfinity(): 15010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = Decimal(self) 15020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans._fix(context) 15030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # self = 0 -> remainder = self, with ideal exponent 15050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ideal_exponent = min(self._exp, other._exp) 15060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 15070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(self._sign, '0', ideal_exponent) 15080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans._fix(context) 15090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # catch most cases of large or small quotient 15110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi expdiff = self.adjusted() - other.adjusted() 15120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if expdiff >= context.prec + 1: 15130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # expdiff >= prec+1 => abs(self/other) > 10**prec 15140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(DivisionImpossible) 15150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if expdiff <= -2: 15160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # expdiff <= -2 => abs(self/other) < 0.1 15170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._rescale(ideal_exponent, context.rounding) 15180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans._fix(context) 15190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # adjust both arguments to have the same exponent, then divide 15210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op1 = _WorkRep(self) 15220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op2 = _WorkRep(other) 15230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if op1.exp >= op2.exp: 15240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op1.int *= 10**(op1.exp - op2.exp) 15250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 15260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op2.int *= 10**(op2.exp - op1.exp) 15270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi q, r = divmod(op1.int, op2.int) 15280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # remainder is r*10**ideal_exponent; other is +/-op2.int * 15290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 10**ideal_exponent. Apply correction to ensure that 15300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # abs(remainder) <= abs(other)/2 15310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if 2*r + (q&1) > op2.int: 15320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r -= op2.int 15330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi q += 1 15340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if q >= 10**context.prec: 15360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(DivisionImpossible) 15370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # result has same sign as self unless r is negative 15390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = self._sign 15400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if r < 0: 15410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = 1-sign 15420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r = -r 15430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(sign, str(r), ideal_exponent) 15450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans._fix(context) 15460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __floordiv__(self, other, context=None): 15480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """self // other""" 15490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other) 15500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 15510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 15520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 15540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 15550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(other, context) 15570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 15580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 15590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity(): 15610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._isinfinity(): 15620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 'INF // INF') 15630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 15640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _SignedInfinity[self._sign ^ other._sign] 15650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not other: 15670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self: 15680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(DivisionByZero, 'x // 0', 15690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._sign ^ other._sign) 15700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 15710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(DivisionUndefined, '0 // 0') 15720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._divide(other, context)[0] 15740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __rfloordiv__(self, other, context=None): 15760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Swaps self/other and returns __floordiv__.""" 15770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other) 15780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 15790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 15800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other.__floordiv__(self, context=context) 15810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __float__(self): 15830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Float representation.""" 15840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isnan(): 15850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.is_snan(): 15860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("Cannot convert signaling NaN to float") 15870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = "-nan" if self._sign else "nan" 15880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 15890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = str(self) 15900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return float(s) 15910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __int__(self): 15930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Converts self to an int, truncating if necessary.""" 15940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special: 15950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isnan(): 15960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("Cannot convert NaN to integer") 15970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif self._isinfinity(): 15980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise OverflowError("Cannot convert infinity to integer") 15990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = (-1)**self._sign 16000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._exp >= 0: 16010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return s*int(self._int)*10**self._exp 16020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 16030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return s*int(self._int[:self._exp] or '0') 16040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __trunc__ = __int__ 16060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def real(self): 16080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self 16090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi real = property(real) 16100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def imag(self): 16120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(0) 16130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi imag = property(imag) 16140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def conjugate(self): 16160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self 16170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __complex__(self): 16190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return complex(float(self)) 16200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __long__(self): 16220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Converts to a long. 16230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Equivalent to long(int(self)) 16250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 16260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return long(self.__int__()) 16270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _fix_nan(self, context): 16290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Decapitate the payload of a NaN to fit the context""" 16300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi payload = self._int 16310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # maximum length of payload is precision if _clamp=0, 16330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # precision-1 if _clamp=1. 16340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi max_payload_len = context.prec - context._clamp 16350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if len(payload) > max_payload_len: 16360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi payload = payload[len(payload)-max_payload_len:].lstrip('0') 16370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(self._sign, payload, self._exp, True) 16380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 16390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _fix(self, context): 16410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Round if it is necessary to keep self within prec precision. 16420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Rounds and fixes the exponent. Does not raise on a sNaN. 16440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Arguments: 16460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self - Decimal instance 16470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context - context used. 16480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 16490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special: 16510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isnan(): 16520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # decapitate payload if necessary 16530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._fix_nan(context) 16540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 16550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # self is +/-Infinity; return unaltered 16560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 16570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if self is zero then exponent should be between Etiny and 16590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Emax if _clamp==0, and between Etiny and Etop if _clamp==1. 16600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Etiny = context.Etiny() 16610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Etop = context.Etop() 16620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 16630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp_max = [context.Emax, Etop][context._clamp] 16640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi new_exp = min(max(self._exp, Etiny), exp_max) 16650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if new_exp != self._exp: 16660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Clamped) 16670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(self._sign, '0', new_exp) 16680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 16690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 16700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exp_min is the smallest allowable exponent of the result, 16720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # equal to max(self.adjusted()-context.prec+1, Etiny) 16730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp_min = len(self._int) + self._exp - context.prec 16740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if exp_min > Etop: 16750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # overflow: exp_min > Etop iff self.adjusted() > Emax 16760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = context._raise_error(Overflow, 'above Emax', self._sign) 16770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Inexact) 16780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Rounded) 16790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 16800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self_is_subnormal = exp_min < Etiny 16820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_is_subnormal: 16830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp_min = Etiny 16840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # round if self has too many digits 16860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._exp < exp_min: 16870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi digits = len(self._int) + self._exp - exp_min 16880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if digits < 0: 16890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self = _dec_from_triple(self._sign, '1', exp_min-1) 16900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi digits = 0 16910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rounding_method = self._pick_rounding_function[context.rounding] 16920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi changed = rounding_method(self, digits) 16930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff = self._int[:digits] or '0' 16940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if changed > 0: 16950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff = str(int(coeff)+1) 16960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if len(coeff) > context.prec: 16970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff = coeff[:-1] 16980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp_min += 1 16990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # check whether the rounding pushed the exponent out of range 17010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if exp_min > Etop: 17020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = context._raise_error(Overflow, 'above Emax', self._sign) 17030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 17040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(self._sign, coeff, exp_min) 17050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # raise the appropriate signals, taking care to respect 17070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # the precedence described in the specification 17080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if changed and self_is_subnormal: 17090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Underflow) 17100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_is_subnormal: 17110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Subnormal) 17120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if changed: 17130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Inexact) 17140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Rounded) 17150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not ans: 17160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # raise Clamped on underflow to 0 17170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Clamped) 17180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 17190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_is_subnormal: 17210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Subnormal) 17220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # fold down if _clamp == 1 and self has too few digits 17240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context._clamp == 1 and self._exp > Etop: 17250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Clamped) 17260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self_padded = self._int + '0'*(self._exp - Etop) 17270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(self._sign, self_padded, Etop) 17280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # here self was representable to begin with; return unchanged 17300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 17310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # for each of the rounding functions below: 17330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # self is a finite, nonzero Decimal 17340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # prec is an integer satisfying 0 <= prec < len(self._int) 17350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 17360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # each function returns either -1, 0, or 1, as follows: 17370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 1 indicates that self should be rounded up (away from zero) 17380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 0 indicates that self should be truncated, and that all the 17390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # digits to be truncated are zeros (so the value is unchanged) 17400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # -1 indicates that there are nonzero digits to be truncated 17410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _round_down(self, prec): 17430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Also known as round-towards-0, truncate.""" 17440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if _all_zeros(self._int, prec): 17450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 0 17460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 17470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return -1 17480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _round_up(self, prec): 17500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Rounds away from 0.""" 17510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return -self._round_down(prec) 17520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _round_half_up(self, prec): 17540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Rounds 5 up (away from 0)""" 17550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._int[prec] in '56789': 17560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 1 17570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif _all_zeros(self._int, prec): 17580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 0 17590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 17600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return -1 17610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _round_half_down(self, prec): 17630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Round 5 down""" 17640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if _exact_half(self._int, prec): 17650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return -1 17660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 17670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._round_half_up(prec) 17680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _round_half_even(self, prec): 17700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Round 5 to even, rest to nearest.""" 17710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if _exact_half(self._int, prec) and \ 17720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (prec == 0 or self._int[prec-1] in '02468'): 17730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return -1 17740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 17750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._round_half_up(prec) 17760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _round_ceiling(self, prec): 17780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Rounds up (not away from 0 if negative.)""" 17790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign: 17800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._round_down(prec) 17810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 17820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return -self._round_down(prec) 17830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _round_floor(self, prec): 17850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Rounds down (not towards 0 if negative)""" 17860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self._sign: 17870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._round_down(prec) 17880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 17890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return -self._round_down(prec) 17900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _round_05up(self, prec): 17920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Round down unless digit prec-1 is 0 or 5.""" 17930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if prec and self._int[prec-1] not in '05': 17940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._round_down(prec) 17950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 17960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return -self._round_down(prec) 17970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _pick_rounding_function = dict( 17990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ROUND_DOWN = _round_down, 18000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ROUND_UP = _round_up, 18010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ROUND_HALF_UP = _round_half_up, 18020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ROUND_HALF_DOWN = _round_half_down, 18030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ROUND_HALF_EVEN = _round_half_even, 18040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ROUND_CEILING = _round_ceiling, 18050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ROUND_FLOOR = _round_floor, 18060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ROUND_05UP = _round_05up, 18070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ) 18080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def fma(self, other, third, context=None): 18100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Fused multiply-add. 18110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Returns self*other+third with no rounding of the intermediate 18130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi product self*other. 18140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self and other are multiplied together, with no rounding of 18160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the result. The third operand is then added to the result, 18170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi and a single final rounding is performed. 18180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 18190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 18210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute product; raise InvalidOperation if either operand is 18230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # a signaling NaN or if the product is zero times infinity. 18240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or other._is_special: 18250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 18260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 18270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._exp == 'N': 18280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 'sNaN', self) 18290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._exp == 'N': 18300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 'sNaN', other) 18310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._exp == 'n': 18320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi product = self 18330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif other._exp == 'n': 18340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi product = other 18350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif self._exp == 'F': 18360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not other: 18370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 18380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'INF * 0 in fma') 18390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi product = _SignedInfinity[self._sign ^ other._sign] 18400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif other._exp == 'F': 18410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 18420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 18430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '0 * INF in fma') 18440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi product = _SignedInfinity[self._sign ^ other._sign] 18450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 18460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi product = _dec_from_triple(self._sign ^ other._sign, 18470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi str(int(self._int) * int(other._int)), 18480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._exp + other._exp) 18490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi third = _convert_other(third, raiseit=True) 18510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return product.__add__(third, context) 18520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _power_modulo(self, other, modulo, context=None): 18540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Three argument version of __pow__""" 18550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if can't convert other and modulo to Decimal, raise 18570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # TypeError; there's no point returning NotImplemented (no 18580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # equivalent of __rpow__ for three argument pow) 18590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 18600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi modulo = _convert_other(modulo, raiseit=True) 18610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 18630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 18640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # deal with NaNs: if there are any sNaNs then first one wins, 18660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # (i.e. behaviour for NaNs is identical to that of fma) 18670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self_is_nan = self._isnan() 18680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other_is_nan = other._isnan() 18690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi modulo_is_nan = modulo._isnan() 18700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_is_nan or other_is_nan or modulo_is_nan: 18710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_is_nan == 2: 18720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 'sNaN', 18730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self) 18740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other_is_nan == 2: 18750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 'sNaN', 18760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other) 18770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if modulo_is_nan == 2: 18780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 'sNaN', 18790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi modulo) 18800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_is_nan: 18810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._fix_nan(context) 18820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other_is_nan: 18830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other._fix_nan(context) 18840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return modulo._fix_nan(context) 18850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # check inputs: we apply same restrictions as Python's pow() 18870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not (self._isinteger() and 18880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other._isinteger() and 18890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi modulo._isinteger()): 18900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 18910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'pow() 3rd argument not allowed ' 18920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'unless all arguments are integers') 18930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other < 0: 18940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 18950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'pow() 2nd argument cannot be ' 18960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'negative when 3rd argument specified') 18970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not modulo: 18980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 18990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'pow() 3rd argument cannot be 0') 19000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # additional restriction for decimal: the modulus must be less 19020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # than 10**prec in absolute value 19030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if modulo.adjusted() >= context.prec: 19040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 19050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'insufficient precision: pow() 3rd ' 19060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'argument must not have more than ' 19070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'precision digits') 19080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # define 0**0 == NaN, for consistency with two-argument pow 19100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # (even though it hurts!) 19110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not other and not self: 19120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 19130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'at least one of pow() 1st argument ' 19140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'and 2nd argument must be nonzero ;' 19150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '0**0 is not defined') 19160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute sign of result 19180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._iseven(): 19190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = 0 19200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 19210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = self._sign 19220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # convert modulo to a Python integer, and self and other to 19240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Decimal integers (i.e. force their exponents to be >= 0) 19250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi modulo = abs(int(modulo)) 19260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi base = _WorkRep(self.to_integral_value()) 19270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exponent = _WorkRep(other.to_integral_value()) 19280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute result using integer pow() 19300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi base = (base.int % modulo * pow(10, base.exp, modulo)) % modulo 19310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for i in xrange(exponent.exp): 19320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi base = pow(base, 10, modulo) 19330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi base = pow(base, exponent.int, modulo) 19340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(sign, str(base), 0) 19360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _power_exact(self, other, p): 19380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Attempt to compute self**other exactly. 19390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Given Decimals self and other and an integer p, attempt to 19410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi compute an exact result for the power self**other, with p 19420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi digits of precision. Return None if self**other is not 19430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exactly representable in p digits. 19440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Assumes that elimination of special cases has already been 19460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi performed: self and other must both be nonspecial; self must 19470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi be positive and not numerically equal to 1; other must be 19480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nonzero. For efficiency, other._exp should not be too large, 19490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi so that 10**abs(other._exp) is a feasible calculation.""" 19500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # In the comments below, we write x for the value of self and y for the 19520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # value of other. Write x = xc*10**xe and abs(y) = yc*10**ye, with xc 19530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # and yc positive integers not divisible by 10. 19540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # The main purpose of this method is to identify the *failure* 19560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # of x**y to be exactly representable with as little effort as 19570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # possible. So we look for cheap and easy tests that 19580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # eliminate the possibility of x**y being exact. Only if all 19590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # these tests are passed do we go on to actually compute x**y. 19600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Here's the main idea. Express y as a rational number m/n, with m and 19620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # n relatively prime and n>0. Then for x**y to be exactly 19630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # representable (at *any* precision), xc must be the nth power of a 19640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # positive integer and xe must be divisible by n. If y is negative 19650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # then additionally xc must be a power of either 2 or 5, hence a power 19660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # of 2**n or 5**n. 19670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 19680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # There's a limit to how small |y| can be: if y=m/n as above 19690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # then: 19700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 19710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # (1) if xc != 1 then for the result to be representable we 19720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # need xc**(1/n) >= 2, and hence also xc**|y| >= 2. So 19730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if |y| <= 1/nbits(xc) then xc < 2**nbits(xc) <= 19740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 2**(1/|y|), hence xc**|y| < 2 and the result is not 19750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # representable. 19760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 19770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # (2) if xe != 0, |xe|*(1/n) >= 1, so |xe|*|y| >= 1. Hence if 19780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # |y| < 1/|xe| then the result is not representable. 19790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 19800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Note that since x is not equal to 1, at least one of (1) and 19810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # (2) must apply. Now |y| < 1/nbits(xc) iff |yc|*nbits(xc) < 19820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 10**-ye iff len(str(|yc|*nbits(xc)) <= -ye. 19830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 19840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # There's also a limit to how large y can be, at least if it's 19850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # positive: the normalized result will have coefficient xc**y, 19860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # so if it's representable then xc**y < 10**p, and y < 19870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # p/log10(xc). Hence if y*log10(xc) >= p then the result is 19880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # not exactly representable. 19890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if len(str(abs(yc*xe)) <= -ye then abs(yc*xe) < 10**-ye, 19910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # so |y| < 1/xe and the result is not representable. 19920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Similarly, len(str(abs(yc)*xc_bits)) <= -ye implies |y| 19930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # < 1/nbits(xc). 19940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi x = _WorkRep(self) 19960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xc, xe = x.int, x.exp 19970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while xc % 10 == 0: 19980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xc //= 10 19990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xe += 1 20000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi y = _WorkRep(other) 20020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi yc, ye = y.int, y.exp 20030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while yc % 10 == 0: 20040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi yc //= 10 20050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ye += 1 20060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # case where xc == 1: result is 10**(xe*y), with xe*y 20080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # required to be an integer 20090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if xc == 1: 20100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xe *= yc 20110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # result is now 10**(xe * 10**ye); xe * 10**ye must be integral 20120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while xe % 10 == 0: 20130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xe //= 10 20140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ye += 1 20150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ye < 0: 20160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 20170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exponent = xe * 10**ye 20180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if y.sign == 1: 20190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exponent = -exponent 20200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if other is a nonnegative integer, use ideal exponent 20210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._isinteger() and other._sign == 0: 20220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ideal_exponent = self._exp*int(other) 20230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi zeros = min(exponent-ideal_exponent, p-1) 20240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 20250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi zeros = 0 20260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(0, '1' + '0'*zeros, exponent-zeros) 20270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # case where y is negative: xc must be either a power 20290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # of 2 or a power of 5. 20300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if y.sign == 1: 20310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi last_digit = xc % 10 20320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if last_digit in (2,4,6,8): 20330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # quick test for power of 2 20340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if xc & -xc != xc: 20350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 20360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # now xc is a power of 2; e is its exponent 20370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e = _nbits(xc)-1 20380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # We now have: 20400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 20410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # x = 2**e * 10**xe, e > 0, and y < 0. 20420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 20430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # The exact result is: 20440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 20450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # x**y = 5**(-e*y) * 10**(e*y + xe*y) 20460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 20470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # provided that both e*y and xe*y are integers. Note that if 20480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 5**(-e*y) >= 10**p, then the result can't be expressed 20490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exactly with p digits of precision. 20500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 20510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Using the above, we can guard against large values of ye. 20520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 93/65 is an upper bound for log(10)/log(5), so if 20530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 20540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # ye >= len(str(93*p//65)) 20550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 20560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # then 20570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 20580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5), 20590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 20600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # so 5**(-e*y) >= 10**p, and the coefficient of the result 20610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # can't be expressed in p digits. 20620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # emax >= largest e such that 5**e < 10**p. 20640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi emax = p*93//65 20650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ye >= len(str(emax)): 20660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 20670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Find -e*y and -xe*y; both must be integers 20690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e = _decimal_lshift_exact(e * yc, ye) 20700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xe = _decimal_lshift_exact(xe * yc, ye) 20710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if e is None or xe is None: 20720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 20730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if e > emax: 20750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 20760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xc = 5**e 20770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif last_digit == 5: 20790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # e >= log_5(xc) if xc is a power of 5; we have 20800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # equality all the way up to xc=5**2658 20810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e = _nbits(xc)*28//65 20820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xc, remainder = divmod(5**e, xc) 20830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if remainder: 20840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 20850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while xc % 5 == 0: 20860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xc //= 5 20870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e -= 1 20880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Guard against large values of ye, using the same logic as in 20900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # the 'xc is a power of 2' branch. 10/3 is an upper bound for 20910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # log(10)/log(2). 20920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi emax = p*10//3 20930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ye >= len(str(emax)): 20940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 20950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e = _decimal_lshift_exact(e * yc, ye) 20970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xe = _decimal_lshift_exact(xe * yc, ye) 20980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if e is None or xe is None: 20990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 21000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if e > emax: 21020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 21030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xc = 2**e 21040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 21050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 21060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if xc >= 10**p: 21080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 21090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xe = -e-xe 21100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(0, str(xc), xe) 21110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # now y is positive; find m and n such that y = m/n 21130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ye >= 0: 21140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m, n = yc*10**ye, 1 21150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 21160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if xe != 0 and len(str(abs(yc*xe))) <= -ye: 21170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 21180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xc_bits = _nbits(xc) 21190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if xc != 1 and len(str(abs(yc)*xc_bits)) <= -ye: 21200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 21210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m, n = yc, 10**(-ye) 21220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while m % 2 == n % 2 == 0: 21230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m //= 2 21240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n //= 2 21250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while m % 5 == n % 5 == 0: 21260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m //= 5 21270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n //= 5 21280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute nth root of xc*10**xe 21300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n > 1: 21310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if 1 < xc < 2**n then xc isn't an nth power 21320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if xc != 1 and xc_bits <= n: 21330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 21340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xe, rem = divmod(xe, n) 21360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if rem != 0: 21370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 21380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute nth root of xc using Newton's method 21400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = 1L << -(-_nbits(xc)//n) # initial estimate 21410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while True: 21420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi q, r = divmod(xc, a**(n-1)) 21430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if a <= q: 21440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 21450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 21460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = (a*(n-1) + q)//n 21470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not (a == q and r == 0): 21480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 21490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xc = a 21500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # now xc*10**xe is the nth root of the original xc*10**xe 21520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute mth power of xc*10**xe 21530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if m > p*100//_log10_lb(xc) then m > p/log10(xc), hence xc**m > 21550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 10**p and the result is not representable. 21560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if xc > 1 and m > p*100//_log10_lb(xc): 21570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 21580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xc = xc**m 21590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xe *= m 21600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if xc > 10**p: 21610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 21620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # by this point the result *is* exactly representable 21640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # adjust the exponent to get as close as possible to the ideal 21650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exponent, if necessary 21660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi str_xc = str(xc) 21670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._isinteger() and other._sign == 0: 21680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ideal_exponent = self._exp*int(other) 21690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi zeros = min(xe-ideal_exponent, p-len(str_xc)) 21700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 21710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi zeros = 0 21720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(0, str_xc+'0'*zeros, xe-zeros) 21730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __pow__(self, other, modulo=None, context=None): 21750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return self ** other [ % modulo]. 21760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi With two arguments, compute self**other. 21780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi With three arguments, compute (self**other) % modulo. For the 21800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi three argument form, the following restrictions on the 21810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi arguments hold: 21820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi - all three arguments must be integral 21840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi - other must be nonnegative 21850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi - either self or other (or both) must be nonzero 21860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi - modulo must be nonzero and must have at most p digits, 21870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi where p is the context precision. 21880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If any of these restrictions is violated the InvalidOperation 21900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi flag is raised. 21910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The result of pow(self, other, modulo) is identical to the 21930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result that would be obtained by computing (self**other) % 21940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi modulo with unbounded precision, but is computed more 21950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi efficiently. It is always exact. 21960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 21970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if modulo is not None: 21990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._power_modulo(other, modulo, context) 22000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other) 22020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 22030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 22040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 22060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 22070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # either argument is a NaN => result is NaN 22090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(other, context) 22100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 22110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 22120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 0**0 = NaN (!), x**0 = 1 for nonzero x (including +/-Infinity) 22140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not other: 22150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 22160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, '0 ** 0') 22170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 22180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _One 22190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # result has sign 1 iff self._sign is 1 and other is an odd integer 22210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result_sign = 0 22220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign == 1: 22230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._isinteger(): 22240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not other._iseven(): 22250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result_sign = 1 22260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 22270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # -ve**noninteger = NaN 22280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # (-0)**noninteger = 0**noninteger 22290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self: 22300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 22310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'x ** y with x negative and y not an integer') 22320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # negate self, without doing any unwanted rounding 22330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self = self.copy_negate() 22340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 0**(+ve or Inf)= 0; 0**(-ve or -Inf) = Infinity 22360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 22370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._sign == 0: 22380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(result_sign, '0', 0) 22390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 22400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _SignedInfinity[result_sign] 22410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Inf**(+ve or Inf) = Inf; Inf**(-ve or -Inf) = 0 22430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity(): 22440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._sign == 0: 22450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _SignedInfinity[result_sign] 22460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 22470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(result_sign, '0', 0) 22480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 1**other = 1, but the choice of exponent and the flags 22500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # depend on the exponent of self, and on whether other is a 22510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # positive integer, a negative integer, or neither 22520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self == _One: 22530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._isinteger(): 22540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exp = max(self._exp*max(int(other), 0), 22550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 1-context.prec) but evaluating int(other) directly 22560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # is dangerous until we know other is small (other 22570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # could be 1e999999999) 22580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._sign == 1: 22590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi multiplier = 0 22600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif other > context.prec: 22610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi multiplier = context.prec 22620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 22630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi multiplier = int(other) 22640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = self._exp * multiplier 22660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if exp < 1-context.prec: 22670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = 1-context.prec 22680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Rounded) 22690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 22700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Inexact) 22710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Rounded) 22720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = 1-context.prec 22730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(result_sign, '1'+'0'*-exp, exp) 22750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute adjusted exponent of self 22770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self_adj = self.adjusted() 22780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # self ** infinity is infinity if self > 1, 0 if self < 1 22800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # self ** -infinity is infinity if self < 1, 0 if self > 1 22810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._isinfinity(): 22820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if (other._sign == 0) == (self_adj < 0): 22830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(result_sign, '0', 0) 22840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 22850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _SignedInfinity[result_sign] 22860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # from here on, the result always goes through the call 22880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # to _fix at the end of this function. 22890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = None 22900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exact = False 22910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # crude test to catch cases of extreme overflow/underflow. If 22930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # log10(self)*other >= 10**bound and bound >= len(str(Emax)) 22940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # then 10**bound >= 10**len(str(Emax)) >= Emax+1 and hence 22950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # self**other >= 10**(Emax+1), so overflow occurs. The test 22960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # for underflow is similar. 22970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi bound = self._log10_exp_bound() + other.adjusted() 22980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if (self_adj >= 0) == (other._sign == 0): 22990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # self > 1 and other +ve, or self < 1 and other -ve 23000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # possibility of overflow 23010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if bound >= len(str(context.Emax)): 23020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(result_sign, '1', context.Emax+1) 23030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 23040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # self > 1 and other -ve, or self < 1 and other +ve 23050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # possibility of underflow to 0 23060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Etiny = context.Etiny() 23070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if bound >= len(str(-Etiny)): 23080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(result_sign, '1', Etiny-1) 23090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # try for an exact result with precision +1 23110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans is None: 23120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._power_exact(other, context.prec + 1) 23130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans is not None: 23140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if result_sign == 1: 23150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(1, ans._int, ans._exp) 23160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exact = True 23170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # usual case: inexact result, x**y computed directly as exp(y*log(x)) 23190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans is None: 23200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p = context.prec 23210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi x = _WorkRep(self) 23220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xc, xe = x.int, x.exp 23230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi y = _WorkRep(other) 23240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi yc, ye = y.int, y.exp 23250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if y.sign == 1: 23260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi yc = -yc 23270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute correctly rounded result: start with precision +3, 23290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # then increase precision until result is unambiguously roundable 23300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi extra = 3 23310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while True: 23320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff, exp = _dpower(xc, xe, yc, ye, p+extra) 23330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if coeff % (5*10**(len(str(coeff))-p-1)): 23340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 23350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi extra += 3 23360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(result_sign, str(coeff), exp) 23380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # unlike exp, ln and log10, the power function respects the 23400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # rounding mode; no need to switch to ROUND_HALF_EVEN here 23410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # There's a difficulty here when 'other' is not an integer and 23430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # the result is exact. In this case, the specification 23440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # requires that the Inexact flag be raised (in spite of 23450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exactness), but since the result is exact _fix won't do this 23460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # for us. (Correspondingly, the Underflow signal should also 23470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # be raised for subnormal results.) We can't directly raise 23480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # these signals either before or after calling _fix, since 23490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # that would violate the precedence for signals. So we wrap 23500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # the ._fix call in a temporary context, and reraise 23510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # afterwards. 23520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if exact and not other._isinteger(): 23530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # pad with zeros up to length context.prec+1 if necessary; this 23540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # ensures that the Rounded signal will be raised. 23550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if len(ans._int) <= context.prec: 23560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi expdiff = context.prec + 1 - len(ans._int) 23570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(ans._sign, ans._int+'0'*expdiff, 23580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans._exp-expdiff) 23590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # create a copy of the current context, with cleared flags/traps 23610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newcontext = context.copy() 23620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newcontext.clear_flags() 23630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for exception in _signals: 23640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newcontext.traps[exception] = 0 23650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # round in the new context 23670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(newcontext) 23680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # raise Inexact, and if necessary, Underflow 23700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newcontext._raise_error(Inexact) 23710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if newcontext.flags[Subnormal]: 23720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newcontext._raise_error(Underflow) 23730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # propagate signals to the original context; _fix could 23750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # have raised any of Overflow, Underflow, Subnormal, 23760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Inexact, Rounded, Clamped. Overflow needs the correct 23770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # arguments. Note that the order of the exceptions is 23780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # important here. 23790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if newcontext.flags[Overflow]: 23800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Overflow, 'above Emax', ans._sign) 23810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for exception in Underflow, Subnormal, Inexact, Rounded, Clamped: 23820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if newcontext.flags[exception]: 23830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(exception) 23840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 23860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(context) 23870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 23890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __rpow__(self, other, context=None): 23910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Swaps self/other and returns __pow__.""" 23920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other) 23930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other is NotImplemented: 23940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 23950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other.__pow__(self, context=context) 23960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def normalize(self, context=None): 23980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Normalize- strip trailing 0s, change anything equal to 0 to 0e0""" 23990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 24010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 24020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special: 24040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(context=context) 24050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 24060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 24070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dup = self._fix(context) 24090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if dup._isinfinity(): 24100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return dup 24110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not dup: 24130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(dup._sign, '0', 0) 24140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp_max = [context.Emax, context.Etop()][context._clamp] 24150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi end = len(dup._int) 24160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = dup._exp 24170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while dup._int[end-1] == '0' and exp < exp_max: 24180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp += 1 24190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi end -= 1 24200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(dup._sign, dup._int[:end], exp) 24210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def quantize(self, exp, rounding=None, context=None, watchexp=True): 24230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Quantize self so its exponent is the same as that of exp. 24240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Similar to self._rescale(exp._exp) but with error checking. 24260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 24270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = _convert_other(exp, raiseit=True) 24280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 24300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 24310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if rounding is None: 24320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rounding = context.rounding 24330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or exp._is_special: 24350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(exp, context) 24360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 24370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 24380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if exp._isinfinity() or self._isinfinity(): 24400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if exp._isinfinity() and self._isinfinity(): 24410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) # if both are inf, it is OK 24420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 24430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'quantize with one INF') 24440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if we're not watching exponents, do a simple rescale 24460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not watchexp: 24470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._rescale(exp._exp, rounding) 24480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # raise Inexact and Rounded where appropriate 24490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans._exp > self._exp: 24500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Rounded) 24510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans != self: 24520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Inexact) 24530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 24540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exp._exp should be between Etiny and Emax 24560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not (context.Etiny() <= exp._exp <= context.Emax): 24570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 24580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'target exponent out of bounds in quantize') 24590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 24610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(self._sign, '0', exp._exp) 24620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans._fix(context) 24630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self_adjusted = self.adjusted() 24650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_adjusted > context.Emax: 24660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 24670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'exponent of quantize result too large for current context') 24680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_adjusted - exp._exp + 1 > context.prec: 24690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 24700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'quantize result has too many digits for current context') 24710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._rescale(exp._exp, rounding) 24730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans.adjusted() > context.Emax: 24740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 24750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'exponent of quantize result too large for current context') 24760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if len(ans._int) > context.prec: 24770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 24780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'quantize result has too many digits for current context') 24790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # raise appropriate flags 24810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans and ans.adjusted() < context.Emin: 24820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Subnormal) 24830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans._exp > self._exp: 24840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans != self: 24850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Inexact) 24860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Rounded) 24870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # call to fix takes care of any necessary folddown, and 24890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # signals Clamped if necessary 24900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(context) 24910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 24920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def same_quantum(self, other): 24940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if self and other have the same exponent; otherwise 24950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False. 24960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If either operand is a special value, the following rules are used: 24980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi * return True if both operands are infinities 24990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi * return True if both operands are NaNs 25000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi * otherwise, return False. 25010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 25020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 25030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or other._is_special: 25040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return (self.is_nan() and other.is_nan() or 25050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.is_infinite() and other.is_infinite()) 25060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._exp == other._exp 25070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _rescale(self, exp, rounding): 25090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Rescale self so that the exponent is exp, either by padding with zeros 25100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi or by truncating digits, using the given rounding mode. 25110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Specials are returned without change. This operation is 25130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi quiet: it raises no flags, and uses no information from the 25140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context. 25150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = exp to scale to (an integer) 25170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rounding = rounding mode 25180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 25190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special: 25200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 25210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 25220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(self._sign, '0', exp) 25230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._exp >= exp: 25250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # pad answer with zeros if necessary 25260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(self._sign, 25270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._int + '0'*(self._exp - exp), exp) 25280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # too many digits; round and lose data. If self.adjusted() < 25300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exp-1, replace self by 10**(exp-1) before rounding 25310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi digits = len(self._int) + self._exp - exp 25320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if digits < 0: 25330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self = _dec_from_triple(self._sign, '1', exp-1) 25340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi digits = 0 25350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi this_function = self._pick_rounding_function[rounding] 25360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi changed = this_function(self, digits) 25370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff = self._int[:digits] or '0' 25380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if changed == 1: 25390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff = str(int(coeff)+1) 25400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(self._sign, coeff, exp) 25410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _round(self, places, rounding): 25430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Round a nonzero, nonspecial Decimal to a fixed number of 25440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi significant figures, using the given rounding mode. 25450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Infinities, NaNs and zeros are returned unaltered. 25470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This operation is quiet: it raises no flags, and uses no 25490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi information from the context. 25500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 25520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if places <= 0: 25530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("argument should be at least 1 in _round") 25540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or not self: 25550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 25560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._rescale(self.adjusted()+1-places, rounding) 25570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # it can happen that the rescale alters the adjusted exponent; 25580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # for example when rounding 99.97 to 3 significant figures. 25590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # When this happens we end up with an extra 0 at the end of 25600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # the number; a second rescale fixes this. 25610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans.adjusted() != self.adjusted(): 25620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._rescale(ans.adjusted()+1-places, rounding) 25630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 25640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def to_integral_exact(self, rounding=None, context=None): 25660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Rounds to a nearby integer. 25670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If no rounding mode is specified, take the rounding mode from 25690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the context. This method raises the Rounded and Inexact flags 25700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi when appropriate. 25710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi See also: to_integral_value, which does exactly the same as 25730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi this method except that it doesn't raise Inexact or Rounded. 25740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 25750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special: 25760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(context=context) 25770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 25780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 25790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 25800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._exp >= 0: 25810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 25820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 25830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(self._sign, '0', 0) 25840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 25850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 25860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if rounding is None: 25870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rounding = context.rounding 25880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._rescale(0, rounding) 25890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans != self: 25900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Inexact) 25910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Rounded) 25920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 25930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def to_integral_value(self, rounding=None, context=None): 25950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Rounds to the nearest integer, without raising inexact, rounded.""" 25960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 25970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 25980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if rounding is None: 25990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rounding = context.rounding 26000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special: 26010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(context=context) 26020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 26030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 26040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 26050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._exp >= 0: 26060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 26070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 26080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._rescale(0, rounding) 26090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # the method name changed, but we provide also the old one, for compatibility 26110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi to_integral = to_integral_value 26120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def sqrt(self, context=None): 26140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return the square root of self.""" 26150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 26160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 26170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special: 26190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(context=context) 26200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 26210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 26220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity() and self._sign == 0: 26240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 26250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 26270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exponent = self._exp // 2. sqrt(-0) = -0 26280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(self._sign, '0', self._exp // 2) 26290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans._fix(context) 26300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign == 1: 26320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0') 26330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # At this point self represents a positive number. Let p be 26350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # the desired precision and express self in the form c*100**e 26360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # with c a positive real number and e an integer, c and e 26370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # being chosen so that 100**(p-1) <= c < 100**p. Then the 26380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # (exact) square root of self is sqrt(c)*10**e, and 10**(p-1) 26390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # <= sqrt(c) < 10**p, so the closest representable Decimal at 26400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # precision p is n*10**e where n = round_half_even(sqrt(c)), 26410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # the closest integer to sqrt(c) with the even integer chosen 26420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # in the case of a tie. 26430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 26440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # To ensure correct rounding in all cases, we use the 26450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # following trick: we compute the square root to an extra 26460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # place (precision p+1 instead of precision p), rounding down. 26470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Then, if the result is inexact and its last digit is 0 or 5, 26480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # we increase the last digit to 1 or 6 respectively; if it's 26490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exact we leave the last digit alone. Now the final round to 26500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # p places (or fewer in the case of underflow) will round 26510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # correctly and raise the appropriate flags. 26520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # use an extra digit of precision 26540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi prec = context.prec+1 26550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # write argument in the form c*100**e where e = self._exp//2 26570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # is the 'ideal' exponent, to be used if the square root is 26580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exactly representable. l is the number of 'digits' of c in 26590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # base 100, so that 100**(l-1) <= c < 100**l. 26600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op = _WorkRep(self) 26610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e = op.exp >> 1 26620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if op.exp & 1: 26630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = op.int * 10 26640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi l = (len(self._int) >> 1) + 1 26650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 26660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = op.int 26670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi l = len(self._int)+1 >> 1 26680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # rescale so that c has exactly prec base 100 'digits' 26700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi shift = prec-l 26710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if shift >= 0: 26720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c *= 100**shift 26730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exact = True 26740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 26750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c, remainder = divmod(c, 100**-shift) 26760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exact = not remainder 26770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e -= shift 26780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # find n = floor(sqrt(c)) using Newton's method 26800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n = 10**prec 26810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while True: 26820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi q = c//n 26830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n <= q: 26840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 26850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 26860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n = n + q >> 1 26870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exact = exact and n*n == c 26880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if exact: 26900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # result is exact; rescale to use ideal exponent e 26910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if shift >= 0: 26920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # assert n % 10**shift == 0 26930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n //= 10**shift 26940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 26950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n *= 10**-shift 26960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e += shift 26970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 26980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # result is not exact; fix last digit as described above 26990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n % 5 == 0: 27000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n += 1 27010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(0, str(n), e) 27030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # round, and fit to current context 27050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = context._shallow_copy() 27060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rounding = context._set_rounding(ROUND_HALF_EVEN) 27070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(context) 27080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context.rounding = rounding 27090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 27110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def max(self, other, context=None): 27130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the larger value. 27140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Like max(self, other) except if one is not a number, returns 27160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi NaN (and signals if one is sNaN). Also rounds. 27170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 27180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 27190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 27210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 27220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or other._is_special: 27240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # If one operand is a quiet NaN and the other is number, then the 27250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # number is always returned 27260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sn = self._isnan() 27270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi on = other._isnan() 27280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if sn or on: 27290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if on == 1 and sn == 0: 27300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._fix(context) 27310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if sn == 1 and on == 0: 27320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other._fix(context) 27330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._check_nans(other, context) 27340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = self._cmp(other) 27360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if c == 0: 27370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # If both operands are finite and equal in numerical value 27380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # then an ordering is applied: 27390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 27400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # If the signs differ then max returns the operand with the 27410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # positive sign and min returns the operand with the negative sign 27420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 27430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # If the signs are the same then the exponent is used to select 27440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # the result. This is exactly the ordering used in compare_total. 27450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = self.compare_total(other) 27460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if c == -1: 27480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = other 27490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 27500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self 27510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans._fix(context) 27530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def min(self, other, context=None): 27550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the smaller value. 27560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Like min(self, other) except if one is not a number, returns 27580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi NaN (and signals if one is sNaN). Also rounds. 27590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 27600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 27610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 27630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 27640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or other._is_special: 27660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # If one operand is a quiet NaN and the other is number, then the 27670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # number is always returned 27680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sn = self._isnan() 27690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi on = other._isnan() 27700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if sn or on: 27710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if on == 1 and sn == 0: 27720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._fix(context) 27730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if sn == 1 and on == 0: 27740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other._fix(context) 27750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._check_nans(other, context) 27760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = self._cmp(other) 27780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if c == 0: 27790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = self.compare_total(other) 27800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if c == -1: 27820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self 27830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 27840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = other 27850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans._fix(context) 27870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _isinteger(self): 27890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns whether self is an integer""" 27900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special: 27910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 27920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._exp >= 0: 27930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return True 27940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rest = self._int[self._exp:] 27950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return rest == '0'*len(rest) 27960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _iseven(self): 27980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns True if self is even. Assumes self is an integer.""" 27990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self or self._exp > 0: 28000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return True 28010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._int[-1+self._exp] in '02468' 28020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def adjusted(self): 28040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return the adjusted exponent of self""" 28050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 28060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._exp + len(self._int) - 1 28070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # If NaN or Infinity, self._exp is string 28080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except TypeError: 28090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 0 28100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def canonical(self, context=None): 28120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the same Decimal object. 28130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi As we do not have different encodings for the same number, the 28150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi received object already is in its canonical form. 28160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 28170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self 28180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def compare_signal(self, other, context=None): 28200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compares self to the other operand numerically. 28210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi It's pretty much like compare(), but all NaNs signal, with signaling 28230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi NaNs taking precedence over quiet NaNs. 28240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 28250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit = True) 28260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._compare_check_nans(other, context) 28270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 28280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 28290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.compare(other, context=context) 28300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def compare_total(self, other): 28320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compares self to other using the abstract representations. 28330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This is not like the standard compare, which use their numerical 28350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi value. Note that a total ordering is defined for all possible abstract 28360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi representations. 28370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 28380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 28390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if one is negative and the other is positive, it's easy 28410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign and not other._sign: 28420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NegativeOne 28430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self._sign and other._sign: 28440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _One 28450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = self._sign 28460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # let's handle both NaN types 28480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self_nan = self._isnan() 28490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other_nan = other._isnan() 28500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_nan or other_nan: 28510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_nan == other_nan: 28520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compare payloads as though they're integers 28530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self_key = len(self._int), self._int 28540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other_key = len(other._int), other._int 28550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_key < other_key: 28560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if sign: 28570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _One 28580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 28590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NegativeOne 28600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_key > other_key: 28610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if sign: 28620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NegativeOne 28630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 28640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _One 28650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _Zero 28660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if sign: 28680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_nan == 1: 28690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NegativeOne 28700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other_nan == 1: 28710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _One 28720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_nan == 2: 28730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NegativeOne 28740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other_nan == 2: 28750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _One 28760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 28770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_nan == 1: 28780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _One 28790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other_nan == 1: 28800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NegativeOne 28810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self_nan == 2: 28820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _One 28830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other_nan == 2: 28840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NegativeOne 28850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self < other: 28870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NegativeOne 28880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self > other: 28890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _One 28900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._exp < other._exp: 28920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if sign: 28930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _One 28940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 28950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NegativeOne 28960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._exp > other._exp: 28970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if sign: 28980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NegativeOne 28990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 29000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _One 29010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _Zero 29020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def compare_total_mag(self, other): 29050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compares self to other using abstract repr., ignoring sign. 29060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Like compare_total, but with operand's sign ignored and assumed to be 0. 29080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 29090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 29100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = self.copy_abs() 29120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi o = other.copy_abs() 29130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return s.compare_total(o) 29140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def copy_abs(self): 29160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns a copy with the sign set to 0. """ 29170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(0, self._int, self._exp, self._is_special) 29180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def copy_negate(self): 29200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns a copy with the sign inverted.""" 29210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign: 29220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(0, self._int, self._exp, self._is_special) 29230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 29240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(1, self._int, self._exp, self._is_special) 29250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def copy_sign(self, other): 29270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns self with the sign of other.""" 29280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 29290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(other._sign, self._int, 29300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._exp, self._is_special) 29310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def exp(self, context=None): 29330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns e ** self.""" 29340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 29360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 29370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exp(NaN) = NaN 29390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(context=context) 29400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 29410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 29420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exp(-Infinity) = 0 29440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity() == -1: 29450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _Zero 29460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exp(0) = 1 29480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 29490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _One 29500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exp(Infinity) = Infinity 29520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity() == 1: 29530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 29540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # the result is now guaranteed to be inexact (the true 29560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # mathematical result is transcendental). There's no need to 29570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # raise Rounded and Inexact here---they'll always be raised as 29580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # a result of the call to _fix. 29590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p = context.prec 29600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi adj = self.adjusted() 29610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # we only need to do any computation for quite a small range 29630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # of adjusted exponents---for example, -29 <= adj <= 10 for 29640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # the default context. For smaller exponent the result is 29650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # indistinguishable from 1 at the given precision, while for 29660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # larger exponent the result either overflows or underflows. 29670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign == 0 and adj > len(str((context.Emax+1)*3)): 29680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # overflow 29690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(0, '1', context.Emax+1) 29700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif self._sign == 1 and adj > len(str((-context.Etiny()+1)*3)): 29710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # underflow to 0 29720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(0, '1', context.Etiny()-1) 29730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif self._sign == 0 and adj < -p: 29740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # p+1 digits; final round will raise correct flags 29750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(0, '1' + '0'*(p-1) + '1', -p) 29760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif self._sign == 1 and adj < -p-1: 29770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # p+1 digits; final round will raise correct flags 29780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(0, '9'*(p+1), -p-1) 29790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # general case 29800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 29810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op = _WorkRep(self) 29820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c, e = op.int, op.exp 29830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if op.sign == 1: 29840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = -c 29850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute correctly rounded result: increase precision by 29870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 3 digits at a time until we get an unambiguously 29880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # roundable result 29890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi extra = 3 29900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while True: 29910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff, exp = _dexp(c, e, p+extra) 29920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if coeff % (5*10**(len(str(coeff))-p-1)): 29930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 29940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi extra += 3 29950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(0, str(coeff), exp) 29970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # at this stage, ans should round correctly with *any* 29990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # rounding mode, not just with ROUND_HALF_EVEN 30000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = context._shallow_copy() 30010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rounding = context._set_rounding(ROUND_HALF_EVEN) 30020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(context) 30030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context.rounding = rounding 30040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 30060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_canonical(self): 30080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if self is canonical; otherwise return False. 30090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Currently, the encoding of a Decimal instance is always 30110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi canonical, so this method returns True for any Decimal. 30120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 30130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return True 30140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_finite(self): 30160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if self is finite; otherwise return False. 30170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi A Decimal instance is considered finite if it is neither 30190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi infinite nor a NaN. 30200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 30210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return not self._is_special 30220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_infinite(self): 30240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if self is infinite; otherwise return False.""" 30250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._exp == 'F' 30260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_nan(self): 30280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if self is a qNaN or sNaN; otherwise return False.""" 30290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._exp in ('n', 'N') 30300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_normal(self, context=None): 30320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if self is a normal number; otherwise return False.""" 30330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or not self: 30340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 30350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 30360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 30370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context.Emin <= self.adjusted() 30380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_qnan(self): 30400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if self is a quiet NaN; otherwise return False.""" 30410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._exp == 'n' 30420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_signed(self): 30440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if self is negative; otherwise return False.""" 30450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._sign == 1 30460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_snan(self): 30480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if self is a signaling NaN; otherwise return False.""" 30490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._exp == 'N' 30500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_subnormal(self, context=None): 30520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if self is subnormal; otherwise return False.""" 30530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or not self: 30540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 30550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 30560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 30570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.adjusted() < context.Emin 30580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_zero(self): 30600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if self is a zero; otherwise return False.""" 30610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return not self._is_special and self._int == '0' 30620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _ln_exp_bound(self): 30640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compute a lower bound for the adjusted exponent of self.ln(). 30650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi In other words, compute r such that self.ln() >= 10**r. Assumes 30660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi that self is finite and positive and that self != 1. 30670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 30680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # for 0.1 <= x <= 10 we use the inequalities 1-1/x <= ln(x) <= x-1 30700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi adj = self._exp + len(self._int) - 1 30710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if adj >= 1: 30720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # argument >= 10; we use 23/10 = 2.3 as a lower bound for ln(10) 30730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return len(str(adj*23//10)) - 1 30740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if adj <= -2: 30750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # argument <= 0.1 30760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return len(str((-1-adj)*23//10)) - 1 30770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op = _WorkRep(self) 30780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c, e = op.int, op.exp 30790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if adj == 0: 30800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 1 < self < 10 30810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi num = str(c-10**-e) 30820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi den = str(c) 30830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return len(num) - len(den) - (num < den) 30840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # adj == -1, 0.1 <= self < 1 30850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return e + len(str(10**-e - c)) - 1 30860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def ln(self, context=None): 30890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the natural (base e) logarithm of self.""" 30900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 30920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 30930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # ln(NaN) = NaN 30950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(context=context) 30960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 30970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 30980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # ln(0.0) == -Infinity 31000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 31010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NegativeInfinity 31020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # ln(Infinity) = Infinity 31040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity() == 1: 31050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _Infinity 31060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # ln(1.0) == 0.0 31080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self == _One: 31090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _Zero 31100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # ln(negative) raises InvalidOperation 31120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign == 1: 31130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 31140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'ln of a negative value') 31150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # result is irrational, so necessarily inexact 31170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op = _WorkRep(self) 31180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c, e = op.int, op.exp 31190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p = context.prec 31200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # correctly rounded result: repeatedly increase precision by 3 31220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # until we get an unambiguously roundable result 31230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi places = p - self._ln_exp_bound() + 2 # at least p+3 places 31240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while True: 31250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff = _dlog(c, e, places) 31260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # assert len(str(abs(coeff)))-p >= 1 31270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if coeff % (5*10**(len(str(abs(coeff)))-p-1)): 31280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 31290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi places += 3 31300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) 31310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = context._shallow_copy() 31330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rounding = context._set_rounding(ROUND_HALF_EVEN) 31340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(context) 31350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context.rounding = rounding 31360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 31370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _log10_exp_bound(self): 31390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compute a lower bound for the adjusted exponent of self.log10(). 31400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi In other words, find r such that self.log10() >= 10**r. 31410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Assumes that self is finite and positive and that self != 1. 31420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 31430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # For x >= 10 or x < 0.1 we only need a bound on the integer 31450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # part of log10(self), and this comes directly from the 31460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exponent of x. For 0.1 <= x <= 10 we use the inequalities 31470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 1-1/x <= log(x) <= x-1. If x > 1 we have |log10(x)| > 31480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # (1-1/x)/2.31 > 0. If x < 1 then |log10(x)| > (1-x)/2.31 > 0 31490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi adj = self._exp + len(self._int) - 1 31510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if adj >= 1: 31520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # self >= 10 31530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return len(str(adj))-1 31540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if adj <= -2: 31550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # self < 0.1 31560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return len(str(-1-adj))-1 31570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op = _WorkRep(self) 31580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c, e = op.int, op.exp 31590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if adj == 0: 31600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 1 < self < 10 31610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi num = str(c-10**-e) 31620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi den = str(231*c) 31630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return len(num) - len(den) - (num < den) + 2 31640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # adj == -1, 0.1 <= self < 1 31650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi num = str(10**-e-c) 31660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return len(num) + e - (num < "231") - 1 31670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def log10(self, context=None): 31690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the base 10 logarithm of self.""" 31700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 31720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 31730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # log10(NaN) = NaN 31750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(context=context) 31760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 31770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 31780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # log10(0.0) == -Infinity 31800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 31810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NegativeInfinity 31820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # log10(Infinity) = Infinity 31840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity() == 1: 31850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _Infinity 31860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # log10(negative or -Infinity) raises InvalidOperation 31880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign == 1: 31890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation, 31900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'log10 of a negative value') 31910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # log10(10**n) = n 31930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._int[0] == '1' and self._int[1:] == '0'*(len(self._int) - 1): 31940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # answer may need rounding 31950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = Decimal(self._exp + len(self._int) - 1) 31960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 31970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # result is irrational, so necessarily inexact 31980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi op = _WorkRep(self) 31990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c, e = op.int, op.exp 32000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p = context.prec 32010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # correctly rounded result: repeatedly increase precision 32030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # until result is unambiguously roundable 32040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi places = p-self._log10_exp_bound()+2 32050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while True: 32060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff = _dlog10(c, e, places) 32070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # assert len(str(abs(coeff)))-p >= 1 32080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if coeff % (5*10**(len(str(abs(coeff)))-p-1)): 32090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 32100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi places += 3 32110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) 32120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = context._shallow_copy() 32140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rounding = context._set_rounding(ROUND_HALF_EVEN) 32150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = ans._fix(context) 32160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context.rounding = rounding 32170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 32180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def logb(self, context=None): 32200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ Returns the exponent of the magnitude of self's MSD. 32210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The result is the integer which is the exponent of the magnitude 32230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi of the most significant digit of self (as though it were truncated 32240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi to a single digit while maintaining the value of that digit and 32250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi without limiting the resulting exponent). 32260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 32270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # logb(NaN) = NaN 32280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(context=context) 32290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 32300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 32310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 32330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 32340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # logb(+/-Inf) = +Inf 32360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity(): 32370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _Infinity 32380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # logb(0) = -Inf, DivisionByZero 32400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self: 32410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(DivisionByZero, 'logb(0)', 1) 32420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # otherwise, simply return the adjusted exponent of self, as a 32440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Decimal. Note that no attempt is made to fit the result 32450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # into the current context. 32460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = Decimal(self.adjusted()) 32470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans._fix(context) 32480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _islogical(self): 32500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if self is a logical operand. 32510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi For being logical, it must be a finite number with a sign of 0, 32530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi an exponent of 0, and a coefficient whose digits must all be 32540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi either 0 or 1. 32550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 32560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign != 0 or self._exp != 0: 32570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 32580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for dig in self._int: 32590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if dig not in '01': 32600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 32610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return True 32620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _fill_logical(self, context, opa, opb): 32640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dif = context.prec - len(opa) 32650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if dif > 0: 32660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi opa = '0'*dif + opa 32670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif dif < 0: 32680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi opa = opa[-context.prec:] 32690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dif = context.prec - len(opb) 32700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if dif > 0: 32710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi opb = '0'*dif + opb 32720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif dif < 0: 32730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi opb = opb[-context.prec:] 32740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return opa, opb 32750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def logical_and(self, other, context=None): 32770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Applies an 'and' operation between self and other's digits.""" 32780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 32790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 32800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 32820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self._islogical() or not other._islogical(): 32840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation) 32850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # fill to context.prec 32870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (opa, opb) = self._fill_logical(context, self._int, other._int) 32880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # make the operation, and clean starting zeroes 32900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result = "".join([str(int(a)&int(b)) for a,b in zip(opa,opb)]) 32910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(0, result.lstrip('0') or '0', 0) 32920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def logical_invert(self, context=None): 32940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Invert all its digits.""" 32950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 32960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 32970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.logical_xor(_dec_from_triple(0,'1'*context.prec,0), 32980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context) 32990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def logical_or(self, other, context=None): 33010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Applies an 'or' operation between self and other's digits.""" 33020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 33030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 33040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 33060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self._islogical() or not other._islogical(): 33080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation) 33090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # fill to context.prec 33110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (opa, opb) = self._fill_logical(context, self._int, other._int) 33120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # make the operation, and clean starting zeroes 33140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result = "".join([str(int(a)|int(b)) for a,b in zip(opa,opb)]) 33150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(0, result.lstrip('0') or '0', 0) 33160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def logical_xor(self, other, context=None): 33180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Applies an 'xor' operation between self and other's digits.""" 33190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 33200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 33210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 33230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self._islogical() or not other._islogical(): 33250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation) 33260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # fill to context.prec 33280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (opa, opb) = self._fill_logical(context, self._int, other._int) 33290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # make the operation, and clean starting zeroes 33310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result = "".join([str(int(a)^int(b)) for a,b in zip(opa,opb)]) 33320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(0, result.lstrip('0') or '0', 0) 33330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def max_mag(self, other, context=None): 33350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compares the values numerically with their sign ignored.""" 33360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 33370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 33390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 33400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or other._is_special: 33420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # If one operand is a quiet NaN and the other is number, then the 33430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # number is always returned 33440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sn = self._isnan() 33450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi on = other._isnan() 33460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if sn or on: 33470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if on == 1 and sn == 0: 33480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._fix(context) 33490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if sn == 1 and on == 0: 33500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other._fix(context) 33510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._check_nans(other, context) 33520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = self.copy_abs()._cmp(other.copy_abs()) 33540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if c == 0: 33550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = self.compare_total(other) 33560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if c == -1: 33580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = other 33590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 33600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self 33610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans._fix(context) 33630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def min_mag(self, other, context=None): 33650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compares the values numerically with their sign ignored.""" 33660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 33670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 33690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 33700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special or other._is_special: 33720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # If one operand is a quiet NaN and the other is number, then the 33730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # number is always returned 33740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sn = self._isnan() 33750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi on = other._isnan() 33760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if sn or on: 33770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if on == 1 and sn == 0: 33780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._fix(context) 33790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if sn == 1 and on == 0: 33800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other._fix(context) 33810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._check_nans(other, context) 33820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = self.copy_abs()._cmp(other.copy_abs()) 33840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if c == 0: 33850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = self.compare_total(other) 33860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if c == -1: 33880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self 33890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 33900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = other 33910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans._fix(context) 33930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def next_minus(self, context=None): 33950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the largest representable number smaller than itself.""" 33960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 33970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 33980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(context=context) 34000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 34010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 34020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity() == -1: 34040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _NegativeInfinity 34050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity() == 1: 34060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(0, '9'*context.prec, context.Etop()) 34070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = context.copy() 34090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._set_rounding(ROUND_FLOOR) 34100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._ignore_all_flags() 34110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi new_self = self._fix(context) 34120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if new_self != self: 34130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return new_self 34140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.__sub__(_dec_from_triple(0, '1', context.Etiny()-1), 34150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context) 34160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def next_plus(self, context=None): 34180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the smallest representable number larger than itself.""" 34190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 34200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 34210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(context=context) 34230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 34240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 34250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity() == 1: 34270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _Infinity 34280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity() == -1: 34290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(1, '9'*context.prec, context.Etop()) 34300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = context.copy() 34320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._set_rounding(ROUND_CEILING) 34330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._ignore_all_flags() 34340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi new_self = self._fix(context) 34350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if new_self != self: 34360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return new_self 34370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.__add__(_dec_from_triple(0, '1', context.Etiny()-1), 34380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context) 34390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def next_toward(self, other, context=None): 34410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the number closest to self, in the direction towards other. 34420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The result is the closest representable number to self 34440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (excluding self) that is in the direction towards other, 34450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless both have the same value. If the two operands are 34460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi numerically equal, then the result is a copy of self with the 34470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign set to be the same as the sign of other. 34480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 34490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 34500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 34520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 34530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(other, context) 34550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 34560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 34570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi comparison = self._cmp(other) 34590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if comparison == 0: 34600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.copy_sign(other) 34610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if comparison == -1: 34630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self.next_plus(context) 34640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: # comparison == 1 34650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self.next_minus(context) 34660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # decide which flags to raise using value of ans 34680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans._isinfinity(): 34690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Overflow, 34700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'Infinite result from next_toward', 34710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans._sign) 34720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Inexact) 34730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Rounded) 34740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif ans.adjusted() < context.Emin: 34750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Underflow) 34760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Subnormal) 34770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Inexact) 34780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Rounded) 34790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if precision == 1 then we don't raise Clamped for a 34800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # result 0E-Etiny. 34810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not ans: 34820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._raise_error(Clamped) 34830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 34850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def number_class(self, context=None): 34870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns an indication of the class of self. 34880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 34890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The class is one of the following strings: 34900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sNaN 34910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi NaN 34920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi -Infinity 34930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi -Normal 34940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi -Subnormal 34950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi -Zero 34960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi +Zero 34970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi +Subnormal 34980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi +Normal 34990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi +Infinity 35000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 35010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.is_snan(): 35020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "sNaN" 35030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.is_qnan(): 35040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "NaN" 35050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi inf = self._isinfinity() 35060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if inf == 1: 35070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "+Infinity" 35080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if inf == -1: 35090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "-Infinity" 35100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.is_zero(): 35110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign: 35120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "-Zero" 35130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 35140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "+Zero" 35150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 35160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 35170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.is_subnormal(context=context): 35180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign: 35190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "-Subnormal" 35200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 35210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "+Subnormal" 35220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # just a normal, regular, boring number, :) 35230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._sign: 35240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "-Normal" 35250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 35260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "+Normal" 35270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def radix(self): 35290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Just returns 10, as this is Decimal, :)""" 35300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(10) 35310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def rotate(self, other, context=None): 35330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns a rotated copy of self, value-of-other times.""" 35340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 35350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 35360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 35380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(other, context) 35400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 35410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 35420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._exp != 0: 35440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation) 35450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not (-context.prec <= int(other) <= context.prec): 35460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation) 35470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity(): 35490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 35500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # get values, pad if necessary 35520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi torot = int(other) 35530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rotdig = self._int 35540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi topad = context.prec - len(rotdig) 35550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if topad > 0: 35560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rotdig = '0'*topad + rotdig 35570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif topad < 0: 35580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rotdig = rotdig[-topad:] 35590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # let's rotate! 35610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rotated = rotdig[torot:] + rotdig[:torot] 35620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(self._sign, 35630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rotated.lstrip('0') or '0', self._exp) 35640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def scaleb(self, other, context=None): 35660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns self operand after adding the second value to its exp.""" 35670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 35680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 35690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 35710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(other, context) 35730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 35740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 35750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._exp != 0: 35770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation) 35780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi liminf = -2 * (context.Emax + context.prec) 35790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi limsup = 2 * (context.Emax + context.prec) 35800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not (liminf <= int(other) <= limsup): 35810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation) 35820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity(): 35840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 35850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = _dec_from_triple(self._sign, self._int, self._exp + int(other)) 35870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = d._fix(context) 35880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return d 35890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def shift(self, other, context=None): 35910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns a shifted copy of self, value-of-other times.""" 35920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 35930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 35940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = _convert_other(other, raiseit=True) 35960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 35970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ans = self._check_nans(other, context) 35980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ans: 35990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ans 36000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other._exp != 0: 36020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation) 36030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not (-context.prec <= int(other) <= context.prec): 36040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return context._raise_error(InvalidOperation) 36050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._isinfinity(): 36070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(self) 36080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # get values, pad if necessary 36100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi torot = int(other) 36110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rotdig = self._int 36120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi topad = context.prec - len(rotdig) 36130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if topad > 0: 36140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rotdig = '0'*topad + rotdig 36150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif topad < 0: 36160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rotdig = rotdig[-topad:] 36170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # let's shift! 36190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if torot < 0: 36200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi shifted = rotdig[:torot] 36210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 36220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi shifted = rotdig + '0'*torot 36230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi shifted = shifted[-context.prec:] 36240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _dec_from_triple(self._sign, 36260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi shifted.lstrip('0') or '0', self._exp) 36270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Support for pickling, copy, and deepcopy 36290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __reduce__(self): 36300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return (self.__class__, (str(self),)) 36310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __copy__(self): 36330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if type(self) is Decimal: 36340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self # I'm immutable; therefore I am my own clone 36350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.__class__(str(self)) 36360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __deepcopy__(self, memo): 36380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if type(self) is Decimal: 36390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self # My components are also immutable 36400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.__class__(str(self)) 36410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # PEP 3101 support. the _localeconv keyword argument should be 36430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # considered private: it's provided for ease of testing only. 36440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __format__(self, specifier, context=None, _localeconv=None): 36450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Format a Decimal instance according to the given specifier. 36460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The specifier should be a standard format specifier, with the 36480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi form described in PEP 3101. Formatting types 'e', 'E', 'f', 36490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'F', 'g', 'G', 'n' and '%' are supported. If the formatting 36500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi type is omitted it defaults to 'g' or 'G', depending on the 36510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi value of context.capitals. 36520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 36530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Note: PEP 3101 says that if the type is not present then 36550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # there should be at least one digit after the decimal point. 36560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # We take the liberty of ignoring this requirement for 36570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Decimal---it's presumably there to make sure that 36580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # format(float, '') behaves similarly to str(float). 36590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if context is None: 36600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = getcontext() 36610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi spec = _parse_format_specifier(specifier, _localeconv=_localeconv) 36630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # special values don't care about the type or precision 36650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_special: 36660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = _format_sign(self._sign, spec) 36670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi body = str(self.copy_abs()) 36680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _format_align(sign, body, spec) 36690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # a type of None defaults to 'g' or 'G', depending on context 36710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if spec['type'] is None: 36720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi spec['type'] = ['g', 'G'][context.capitals] 36730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if type is '%', adjust exponent of self accordingly 36750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if spec['type'] == '%': 36760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self = _dec_from_triple(self._sign, self._int, self._exp+2) 36770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # round if necessary, taking rounding mode from the context 36790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rounding = context.rounding 36800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi precision = spec['precision'] 36810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if precision is not None: 36820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if spec['type'] in 'eE': 36830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self = self._round(precision+1, rounding) 36840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif spec['type'] in 'fF%': 36850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self = self._rescale(-precision, rounding) 36860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif spec['type'] in 'gG' and len(self._int) > precision: 36870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self = self._round(precision, rounding) 36880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # special case: zeros with a positive exponent can't be 36890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # represented in fixed point; rescale them to 0e0. 36900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self and self._exp > 0 and spec['type'] in 'fF%': 36910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self = self._rescale(0, rounding) 36920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 36930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # figure out placement of the decimal point 36940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi leftdigits = self._exp + len(self._int) 36950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if spec['type'] in 'eE': 36960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self and precision is not None: 36970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dotplace = 1 - precision 36980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 36990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dotplace = 1 37000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif spec['type'] in 'fF%': 37010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dotplace = leftdigits 37020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif spec['type'] in 'gG': 37030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._exp <= 0 and leftdigits > -6: 37040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dotplace = leftdigits 37050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 37060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dotplace = 1 37070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 37080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # find digits before and after decimal point, and get exponent 37090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if dotplace < 0: 37100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi intpart = '0' 37110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fracpart = '0'*(-dotplace) + self._int 37120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif dotplace > len(self._int): 37130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi intpart = self._int + '0'*(dotplace-len(self._int)) 37140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fracpart = '' 37150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 37160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi intpart = self._int[:dotplace] or '0' 37170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fracpart = self._int[dotplace:] 37180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = leftdigits-dotplace 37190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 37200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # done with the decimal-specific stuff; hand over the rest 37210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # of the formatting to the _format_number function 37220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _format_number(self._sign, intpart, fracpart, exp, spec) 37230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 37240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _dec_from_triple(sign, coefficient, exponent, special=False): 37250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Create a decimal instance directly, without any validation, 37260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi normalization (e.g. removal of leading zeros) or argument 37270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi conversion. 37280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 37290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This function is for *internal use only*. 37300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 37310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 37320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self = object.__new__(Decimal) 37330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._sign = sign 37340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._int = coefficient 37350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._exp = exponent 37360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._is_special = special 37370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 37380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self 37390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 37400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Register Decimal as a kind of Number (an abstract base class). 37410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# However, do not register it as Real (because Decimals are not 37420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# interoperable with floats). 37430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_numbers.Number.register(Decimal) 37440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 37450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 37460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##### Context class ####################################################### 37470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 37480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass _ContextManager(object): 37490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Context manager class to support localcontext(). 37500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 37510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Sets a copy of the supplied context in __enter__() and restores 37520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the previous decimal context in __exit__() 37530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 37540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self, new_context): 37550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.new_context = new_context.copy() 37560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __enter__(self): 37570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.saved_context = getcontext() 37580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi setcontext(self.new_context) 37590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.new_context 37600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __exit__(self, t, v, tb): 37610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi setcontext(self.saved_context) 37620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 37630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Context(object): 37640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Contains the context for a Decimal instance. 37650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 37660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Contains: 37670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi prec - precision (for use in rounding, division, square roots..) 37680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rounding - rounding type (how you round) 37690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi traps - If traps[exception] = 1, then the exception is 37700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raised when it is caused. Otherwise, a value is 37710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi substituted in. 37720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi flags - When an exception is caused, flags[exception] is set. 37730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (Whether or not the trap_enabler is set) 37740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Should be reset by user of Decimal instance. 37750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Emin - Minimum exponent 37760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Emax - Maximum exponent 37770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi capitals - If 1, 1*10^1 is printed as 1E+1. 37780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If 0, printed as 1e1 37790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clamp - If 1, change exponents if too high (Default 0) 37800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 37810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 37820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self, prec=None, rounding=None, 37830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi traps=None, flags=None, 37840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Emin=None, Emax=None, 37850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi capitals=None, _clamp=0, 37860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _ignored_flags=None): 37870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Set defaults; for everything except flags and _ignored_flags, 37880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # inherit from DefaultContext. 37890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 37900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dc = DefaultContext 37910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except NameError: 37920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pass 37930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 37940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.prec = prec if prec is not None else dc.prec 37950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.rounding = rounding if rounding is not None else dc.rounding 37960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.Emin = Emin if Emin is not None else dc.Emin 37970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.Emax = Emax if Emax is not None else dc.Emax 37980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.capitals = capitals if capitals is not None else dc.capitals 37990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._clamp = _clamp if _clamp is not None else dc._clamp 38000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if _ignored_flags is None: 38020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._ignored_flags = [] 38030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 38040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._ignored_flags = _ignored_flags 38050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if traps is None: 38070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.traps = dc.traps.copy() 38080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif not isinstance(traps, dict): 38090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.traps = dict((s, int(s in traps)) for s in _signals) 38100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 38110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.traps = traps 38120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if flags is None: 38140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.flags = dict.fromkeys(_signals, 0) 38150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif not isinstance(flags, dict): 38160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.flags = dict((s, int(s in flags)) for s in _signals) 38170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 38180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.flags = flags 38190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __repr__(self): 38210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Show the current context.""" 38220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = [] 38230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s.append('Context(prec=%(prec)d, rounding=%(rounding)s, ' 38240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' 38250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi % vars(self)) 38260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi names = [f.__name__ for f, v in self.flags.items() if v] 38270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s.append('flags=[' + ', '.join(names) + ']') 38280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi names = [t.__name__ for t, v in self.traps.items() if v] 38290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s.append('traps=[' + ', '.join(names) + ']') 38300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ', '.join(s) + ')' 38310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def clear_flags(self): 38330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Reset all flags to zero""" 38340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for flag in self.flags: 38350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.flags[flag] = 0 38360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _shallow_copy(self): 38380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns a shallow copy from self.""" 38390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nc = Context(self.prec, self.rounding, self.traps, 38400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.flags, self.Emin, self.Emax, 38410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.capitals, self._clamp, self._ignored_flags) 38420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return nc 38430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def copy(self): 38450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns a deep copy from self.""" 38460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nc = Context(self.prec, self.rounding, self.traps.copy(), 38470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.flags.copy(), self.Emin, self.Emax, 38480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.capitals, self._clamp, self._ignored_flags) 38490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return nc 38500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __copy__ = copy 38510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _raise_error(self, condition, explanation = None, *args): 38530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Handles an error 38540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If the flag is in _ignored_flags, returns the default response. 38560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Otherwise, it sets the flag, then, if the corresponding 38570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi trap_enabler is set, it reraises the exception. Otherwise, it returns 38580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the default value after setting the flag. 38590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 38600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi error = _condition_map.get(condition, condition) 38610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if error in self._ignored_flags: 38620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Don't touch the flag 38630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return error().handle(self, *args) 38640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.flags[error] = 1 38660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not self.traps[error]: 38670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # The errors define how to handle themselves. 38680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return condition().handle(self, *args) 38690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Errors should only be risked on copies of the context 38710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # self._ignored_flags = [] 38720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise error(explanation) 38730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _ignore_all_flags(self): 38750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Ignore all flags, if they are raised""" 38760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._ignore_flags(*_signals) 38770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _ignore_flags(self, *flags): 38790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Ignore the flags, if they are raised""" 38800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Do not mutate-- This way, copies of a context leave the original 38810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # alone. 38820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._ignored_flags = (self._ignored_flags + list(flags)) 38830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return list(flags) 38840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _regard_flags(self, *flags): 38860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Stop ignoring the flags, if they are raised""" 38870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if flags and isinstance(flags[0], (tuple,list)): 38880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi flags = flags[0] 38890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for flag in flags: 38900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._ignored_flags.remove(flag) 38910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # We inherit object.__hash__, so we must deny this explicitly 38930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __hash__ = None 38940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def Etiny(self): 38960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns Etiny (= Emin - prec + 1)""" 38970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return int(self.Emin - self.prec + 1) 38980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 38990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def Etop(self): 39000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns maximum exponent (= Emax - prec + 1)""" 39010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return int(self.Emax - self.prec + 1) 39020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _set_rounding(self, type): 39040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Sets the rounding type. 39050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Sets the rounding type, and returns the current (previous) 39070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rounding type. Often used like: 39080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context = context.copy() 39100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # so you don't change the calling context 39110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if an error occurs in the middle. 39120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rounding = context._set_rounding(ROUND_UP) 39130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi val = self.__sub__(other, context=context) 39140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context._set_rounding(rounding) 39150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This will make it round up for that operation. 39170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 39180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rounding = self.rounding 39190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.rounding= type 39200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return rounding 39210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def create_decimal(self, num='0'): 39230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Creates a new Decimal instance but using self as context. 39240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This method implements the to-number operation of the 39260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi IBM Decimal specification.""" 39270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(num, basestring) and num != num.strip(): 39290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._raise_error(ConversionSyntax, 39300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "no trailing or leading whitespace is " 39310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "permitted.") 39320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = Decimal(num, context=self) 39340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if d._isnan() and len(d._int) > self.prec - self._clamp: 39350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._raise_error(ConversionSyntax, 39360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "diagnostic info too long in NaN") 39370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return d._fix(self) 39380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def create_decimal_from_float(self, f): 39400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Creates a new Decimal instance from a float but rounding using self 39410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi as the context. 39420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> context = Context(prec=5, rounding=ROUND_DOWN) 39440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> context.create_decimal_from_float(3.1415926535897932) 39450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3.1415') 39460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> context = Context(prec=5, traps=[Inexact]) 39470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> context.create_decimal_from_float(3.1415926535897932) 39480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Traceback (most recent call last): 39490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ... 39500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Inexact: None 39510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 39530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = Decimal.from_float(f) # An exact conversion 39540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return d._fix(self) # Apply the context rounding 39550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Methods 39570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def abs(self, a): 39580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the absolute value of the operand. 39590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If the operand is negative, the result is the same as using the minus 39610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operation on the operand. Otherwise, the result is the same as using 39620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the plus operation on the operand. 39630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.abs(Decimal('2.1')) 39650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.1') 39660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.abs(Decimal('-100')) 39670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('100') 39680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.abs(Decimal('101.5')) 39690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('101.5') 39700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.abs(Decimal('-101.5')) 39710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('101.5') 39720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.abs(-1) 39730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 39740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 39750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 39760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.__abs__(context=self) 39770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def add(self, a, b): 39790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return the sum of the two operands. 39800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.add(Decimal('12'), Decimal('7.00')) 39820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('19.00') 39830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4')) 39840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.02E+4') 39850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.add(1, Decimal(2)) 39860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3') 39870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.add(Decimal(8), 5) 39880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('13') 39890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.add(5, 5) 39900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('10') 39910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 39920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 39930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r = a.__add__(b, context=self) 39940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if r is NotImplemented: 39950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise TypeError("Unable to convert %s to Decimal" % b) 39960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 39970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return r 39980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 39990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _apply(self, a): 40000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return str(a._fix(self)) 40010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 40020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def canonical(self, a): 40030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the same Decimal object. 40040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 40050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi As we do not have different encodings for the same number, the 40060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi received object already is in its canonical form. 40070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 40080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.canonical(Decimal('2.50')) 40090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.50') 40100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 40110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.canonical(context=self) 40120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 40130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def compare(self, a, b): 40140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compares values numerically. 40150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 40160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If the signs of the operands differ, a value representing each operand 40170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('-1' if the operand is less than zero, '0' if the operand is zero or 40180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi negative zero, or '1' if the operand is greater than zero) is used in 40190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi place of that operand for the comparison instead of the actual 40200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operand. 40210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 40220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The comparison is then effected by subtracting the second operand from 40230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the first and then returning a value according to the result of the 40240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subtraction: '-1' if the result is less than zero, '0' if the result is 40250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi zero or negative zero, or '1' if the result is greater than zero. 40260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 40270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3')) 40280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 40290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1')) 40300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 40310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10')) 40320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 40330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1')) 40340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 40350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3')) 40360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 40370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1')) 40380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 40390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare(1, 2) 40400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 40410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare(Decimal(1), 2) 40420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 40430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare(1, Decimal(2)) 40440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 40450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 40460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 40470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.compare(b, context=self) 40480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 40490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def compare_signal(self, a, b): 40500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compares the values of the two operands numerically. 40510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 40520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi It's pretty much like compare(), but all NaNs signal, with signaling 40530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi NaNs taking precedence over quiet NaNs. 40540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 40550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c = ExtendedContext 40560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.compare_signal(Decimal('2.1'), Decimal('3')) 40570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 40580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.compare_signal(Decimal('2.1'), Decimal('2.1')) 40590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 40600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.flags[InvalidOperation] = 0 40610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> print c.flags[InvalidOperation] 40620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 0 40630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.compare_signal(Decimal('NaN'), Decimal('2.1')) 40640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('NaN') 40650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> print c.flags[InvalidOperation] 40660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1 40670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.flags[InvalidOperation] = 0 40680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> print c.flags[InvalidOperation] 40690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 0 40700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.compare_signal(Decimal('sNaN'), Decimal('2.1')) 40710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('NaN') 40720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> print c.flags[InvalidOperation] 40730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1 40740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.compare_signal(-1, 2) 40750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 40760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.compare_signal(Decimal(-1), 2) 40770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 40780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.compare_signal(-1, Decimal(2)) 40790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 40800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 40810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 40820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.compare_signal(b, context=self) 40830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 40840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def compare_total(self, a, b): 40850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compares two operands using their abstract representation. 40860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 40870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This is not like the standard compare, which use their numerical 40880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi value. Note that a total ordering is defined for all possible abstract 40890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi representations. 40900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 40910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare_total(Decimal('12.73'), Decimal('127.9')) 40920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 40930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare_total(Decimal('-127'), Decimal('12')) 40940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 40950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.3')) 40960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 40970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.30')) 40980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 40990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare_total(Decimal('12.3'), Decimal('12.300')) 41000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 41010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare_total(Decimal('12.3'), Decimal('NaN')) 41020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 41030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare_total(1, 2) 41040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 41050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare_total(Decimal(1), 2) 41060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 41070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.compare_total(1, Decimal(2)) 41080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 41090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 41100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 41110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.compare_total(b) 41120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 41130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def compare_total_mag(self, a, b): 41140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compares two operands using their abstract representation ignoring sign. 41150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 41160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Like compare_total, but with operand's sign ignored and assumed to be 0. 41170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 41180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 41190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.compare_total_mag(b) 41200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 41210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def copy_abs(self, a): 41220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns a copy of the operand with the sign set to 0. 41230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 41240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_abs(Decimal('2.1')) 41250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.1') 41260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_abs(Decimal('-100')) 41270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('100') 41280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_abs(-1) 41290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 41300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 41310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 41320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.copy_abs() 41330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 41340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def copy_decimal(self, a): 41350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns a copy of the decimal object. 41360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 41370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_decimal(Decimal('2.1')) 41380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.1') 41390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_decimal(Decimal('-1.00')) 41400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1.00') 41410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_decimal(1) 41420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 41430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 41440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 41450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(a) 41460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 41470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def copy_negate(self, a): 41480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns a copy of the operand with the sign inverted. 41490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 41500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_negate(Decimal('101.5')) 41510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-101.5') 41520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_negate(Decimal('-101.5')) 41530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('101.5') 41540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_negate(1) 41550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 41560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 41570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 41580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.copy_negate() 41590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 41600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def copy_sign(self, a, b): 41610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Copies the second operand's sign to the first one. 41620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 41630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi In detail, it returns a copy of the first operand with the sign 41640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi equal to the sign of the second operand. 41650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 41660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('7.33')) 41670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.50') 41680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('7.33')) 41690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.50') 41700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('-7.33')) 41710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1.50') 41720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('-7.33')) 41730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1.50') 41740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_sign(1, -2) 41750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 41760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_sign(Decimal(1), -2) 41770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 41780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.copy_sign(1, Decimal(-2)) 41790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 41800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 41810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 41820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.copy_sign(b) 41830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 41840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def divide(self, a, b): 41850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Decimal division in a specified context. 41860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 41870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide(Decimal('1'), Decimal('3')) 41880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.333333333') 41890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide(Decimal('2'), Decimal('3')) 41900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.666666667') 41910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide(Decimal('5'), Decimal('2')) 41920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.5') 41930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide(Decimal('1'), Decimal('10')) 41940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.1') 41950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide(Decimal('12'), Decimal('12')) 41960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 41970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2')) 41980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('4.00') 41990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0')) 42000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.20') 42010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide(Decimal('1000'), Decimal('100')) 42020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('10') 42030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide(Decimal('1000'), Decimal('1')) 42040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1000') 42050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2')) 42060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.20E+6') 42070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide(5, 5) 42080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 42090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide(Decimal(5), 5) 42100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 42110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide(5, Decimal(5)) 42120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 42130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 42140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 42150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r = a.__div__(b, context=self) 42160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if r is NotImplemented: 42170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise TypeError("Unable to convert %s to Decimal" % b) 42180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 42190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return r 42200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 42210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def divide_int(self, a, b): 42220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Divides two numbers and returns the integer part of the result. 42230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 42240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3')) 42250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 42260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3')) 42270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3') 42280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3')) 42290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3') 42300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide_int(10, 3) 42310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3') 42320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide_int(Decimal(10), 3) 42330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3') 42340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divide_int(10, Decimal(3)) 42350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3') 42360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 42370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 42380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r = a.__floordiv__(b, context=self) 42390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if r is NotImplemented: 42400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise TypeError("Unable to convert %s to Decimal" % b) 42410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 42420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return r 42430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 42440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def divmod(self, a, b): 42450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return (a // b, a % b). 42460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 42470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divmod(Decimal(8), Decimal(3)) 42480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (Decimal('2'), Decimal('2')) 42490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divmod(Decimal(8), Decimal(4)) 42500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (Decimal('2'), Decimal('0')) 42510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divmod(8, 4) 42520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (Decimal('2'), Decimal('0')) 42530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divmod(Decimal(8), 4) 42540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (Decimal('2'), Decimal('0')) 42550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.divmod(8, Decimal(4)) 42560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (Decimal('2'), Decimal('0')) 42570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 42580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 42590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r = a.__divmod__(b, context=self) 42600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if r is NotImplemented: 42610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise TypeError("Unable to convert %s to Decimal" % b) 42620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 42630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return r 42640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 42650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def exp(self, a): 42660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns e ** a. 42670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 42680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c = ExtendedContext.copy() 42690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emin = -999 42700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emax = 999 42710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.exp(Decimal('-Infinity')) 42720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 42730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.exp(Decimal('-1')) 42740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.367879441') 42750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.exp(Decimal('0')) 42760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 42770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.exp(Decimal('1')) 42780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.71828183') 42790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.exp(Decimal('0.693147181')) 42800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.00000000') 42810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.exp(Decimal('+Infinity')) 42820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('Infinity') 42830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.exp(10) 42840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('22026.4658') 42850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 42860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a =_convert_other(a, raiseit=True) 42870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.exp(context=self) 42880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 42890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def fma(self, a, b, c): 42900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns a multiplied by b, plus c. 42910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 42920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The first two operands are multiplied together, using multiply, 42930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the third operand is then added to the result of that 42940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi multiplication, using add, all with only one final rounding. 42950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 42960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.fma(Decimal('3'), Decimal('5'), Decimal('7')) 42970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('22') 42980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.fma(Decimal('3'), Decimal('-5'), Decimal('7')) 42990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-8') 43000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.fma(Decimal('888565290'), Decimal('1557.96930'), Decimal('-86087.7578')) 43010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.38435736E+12') 43020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.fma(1, 3, 4) 43030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('7') 43040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.fma(1, Decimal(3), 4) 43050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('7') 43060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.fma(1, 3, Decimal(4)) 43070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('7') 43080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 43090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 43100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.fma(b, c, context=self) 43110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 43120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_canonical(self, a): 43130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if the operand is canonical; otherwise return False. 43140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 43150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Currently, the encoding of a Decimal instance is always 43160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi canonical, so this method returns True for any Decimal. 43170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 43180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_canonical(Decimal('2.50')) 43190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 43200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 43210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.is_canonical() 43220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 43230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_finite(self, a): 43240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if the operand is finite; otherwise return False. 43250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 43260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi A Decimal instance is considered finite if it is neither 43270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi infinite nor a NaN. 43280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 43290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_finite(Decimal('2.50')) 43300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 43310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_finite(Decimal('-0.3')) 43320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 43330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_finite(Decimal('0')) 43340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 43350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_finite(Decimal('Inf')) 43360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 43370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_finite(Decimal('NaN')) 43380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 43390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_finite(1) 43400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 43410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 43420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 43430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.is_finite() 43440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 43450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_infinite(self, a): 43460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if the operand is infinite; otherwise return False. 43470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 43480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_infinite(Decimal('2.50')) 43490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 43500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_infinite(Decimal('-Inf')) 43510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 43520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_infinite(Decimal('NaN')) 43530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 43540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_infinite(1) 43550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 43560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 43570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 43580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.is_infinite() 43590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 43600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_nan(self, a): 43610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if the operand is a qNaN or sNaN; 43620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi otherwise return False. 43630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 43640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_nan(Decimal('2.50')) 43650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 43660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_nan(Decimal('NaN')) 43670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 43680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_nan(Decimal('-sNaN')) 43690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 43700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_nan(1) 43710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 43720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 43730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 43740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.is_nan() 43750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 43760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_normal(self, a): 43770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if the operand is a normal number; 43780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi otherwise return False. 43790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 43800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c = ExtendedContext.copy() 43810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emin = -999 43820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emax = 999 43830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.is_normal(Decimal('2.50')) 43840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 43850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.is_normal(Decimal('0.1E-999')) 43860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 43870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.is_normal(Decimal('0.00')) 43880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 43890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.is_normal(Decimal('-Inf')) 43900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 43910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.is_normal(Decimal('NaN')) 43920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 43930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.is_normal(1) 43940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 43950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 43960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 43970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.is_normal(context=self) 43980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 43990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_qnan(self, a): 44000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if the operand is a quiet NaN; otherwise return False. 44010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 44020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_qnan(Decimal('2.50')) 44030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 44040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_qnan(Decimal('NaN')) 44050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 44060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_qnan(Decimal('sNaN')) 44070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 44080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_qnan(1) 44090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 44100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 44110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 44120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.is_qnan() 44130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 44140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_signed(self, a): 44150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if the operand is negative; otherwise return False. 44160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 44170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_signed(Decimal('2.50')) 44180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 44190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_signed(Decimal('-12')) 44200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 44210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_signed(Decimal('-0')) 44220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 44230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_signed(8) 44240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 44250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_signed(-8) 44260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 44270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 44280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 44290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.is_signed() 44300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 44310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_snan(self, a): 44320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if the operand is a signaling NaN; 44330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi otherwise return False. 44340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 44350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_snan(Decimal('2.50')) 44360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 44370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_snan(Decimal('NaN')) 44380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 44390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_snan(Decimal('sNaN')) 44400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 44410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_snan(1) 44420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 44430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 44440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 44450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.is_snan() 44460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 44470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_subnormal(self, a): 44480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if the operand is subnormal; otherwise return False. 44490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 44500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c = ExtendedContext.copy() 44510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emin = -999 44520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emax = 999 44530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.is_subnormal(Decimal('2.50')) 44540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 44550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.is_subnormal(Decimal('0.1E-999')) 44560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 44570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.is_subnormal(Decimal('0.00')) 44580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 44590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.is_subnormal(Decimal('-Inf')) 44600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 44610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.is_subnormal(Decimal('NaN')) 44620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 44630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.is_subnormal(1) 44640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 44650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 44660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 44670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.is_subnormal(context=self) 44680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 44690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def is_zero(self, a): 44700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return True if the operand is a zero; otherwise return False. 44710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 44720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_zero(Decimal('0')) 44730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 44740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_zero(Decimal('2.50')) 44750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 44760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_zero(Decimal('-0E+2')) 44770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 44780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_zero(1) 44790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 44800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.is_zero(0) 44810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 44820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 44830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 44840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.is_zero() 44850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 44860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def ln(self, a): 44870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the natural (base e) logarithm of the operand. 44880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 44890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c = ExtendedContext.copy() 44900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emin = -999 44910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emax = 999 44920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.ln(Decimal('0')) 44930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-Infinity') 44940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.ln(Decimal('1.000')) 44950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 44960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.ln(Decimal('2.71828183')) 44970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.00000000') 44980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.ln(Decimal('10')) 44990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.30258509') 45000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.ln(Decimal('+Infinity')) 45010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('Infinity') 45020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.ln(1) 45030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 45040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 45050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 45060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.ln(context=self) 45070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 45080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def log10(self, a): 45090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the base 10 logarithm of the operand. 45100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 45110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c = ExtendedContext.copy() 45120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emin = -999 45130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emax = 999 45140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.log10(Decimal('0')) 45150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-Infinity') 45160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.log10(Decimal('0.001')) 45170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-3') 45180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.log10(Decimal('1.000')) 45190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 45200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.log10(Decimal('2')) 45210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.301029996') 45220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.log10(Decimal('10')) 45230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 45240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.log10(Decimal('70')) 45250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.84509804') 45260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.log10(Decimal('+Infinity')) 45270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('Infinity') 45280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.log10(0) 45290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-Infinity') 45300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.log10(1) 45310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 45320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 45330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 45340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.log10(context=self) 45350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 45360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def logb(self, a): 45370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ Returns the exponent of the magnitude of the operand's MSD. 45380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 45390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The result is the integer which is the exponent of the magnitude 45400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi of the most significant digit of the operand (as though the 45410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operand were truncated to a single digit while maintaining the 45420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi value of that digit and without limiting the resulting exponent). 45430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 45440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logb(Decimal('250')) 45450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2') 45460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logb(Decimal('2.50')) 45470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 45480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logb(Decimal('0.03')) 45490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-2') 45500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logb(Decimal('0')) 45510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-Infinity') 45520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logb(1) 45530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 45540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logb(10) 45550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 45560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logb(100) 45570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2') 45580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 45590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 45600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.logb(context=self) 45610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 45620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def logical_and(self, a, b): 45630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Applies the logical operation 'and' between each operand's digits. 45640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 45650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The operands must be both logical numbers. 45660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 45670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_and(Decimal('0'), Decimal('0')) 45680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 45690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_and(Decimal('0'), Decimal('1')) 45700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 45710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_and(Decimal('1'), Decimal('0')) 45720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 45730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_and(Decimal('1'), Decimal('1')) 45740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 45750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_and(Decimal('1100'), Decimal('1010')) 45760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1000') 45770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_and(Decimal('1111'), Decimal('10')) 45780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('10') 45790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_and(110, 1101) 45800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('100') 45810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_and(Decimal(110), 1101) 45820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('100') 45830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_and(110, Decimal(1101)) 45840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('100') 45850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 45860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 45870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.logical_and(b, context=self) 45880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 45890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def logical_invert(self, a): 45900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Invert all the digits in the operand. 45910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 45920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The operand must be a logical number. 45930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 45940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_invert(Decimal('0')) 45950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('111111111') 45960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_invert(Decimal('1')) 45970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('111111110') 45980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_invert(Decimal('111111111')) 45990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 46000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_invert(Decimal('101010101')) 46010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('10101010') 46020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_invert(1101) 46030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('111110010') 46040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 46050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 46060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.logical_invert(context=self) 46070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 46080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def logical_or(self, a, b): 46090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Applies the logical operation 'or' between each operand's digits. 46100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 46110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The operands must be both logical numbers. 46120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 46130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_or(Decimal('0'), Decimal('0')) 46140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 46150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_or(Decimal('0'), Decimal('1')) 46160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 46170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_or(Decimal('1'), Decimal('0')) 46180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 46190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_or(Decimal('1'), Decimal('1')) 46200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 46210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_or(Decimal('1100'), Decimal('1010')) 46220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1110') 46230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_or(Decimal('1110'), Decimal('10')) 46240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1110') 46250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_or(110, 1101) 46260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1111') 46270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_or(Decimal(110), 1101) 46280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1111') 46290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_or(110, Decimal(1101)) 46300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1111') 46310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 46320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 46330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.logical_or(b, context=self) 46340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 46350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def logical_xor(self, a, b): 46360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Applies the logical operation 'xor' between each operand's digits. 46370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 46380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The operands must be both logical numbers. 46390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 46400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('0')) 46410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 46420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('1')) 46430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 46440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('0')) 46450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 46460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('1')) 46470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 46480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_xor(Decimal('1100'), Decimal('1010')) 46490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('110') 46500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_xor(Decimal('1111'), Decimal('10')) 46510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1101') 46520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_xor(110, 1101) 46530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1011') 46540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_xor(Decimal(110), 1101) 46550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1011') 46560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.logical_xor(110, Decimal(1101)) 46570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1011') 46580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 46590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 46600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.logical_xor(b, context=self) 46610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 46620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def max(self, a, b): 46630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """max compares two values numerically and returns the maximum. 46640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 46650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If either operand is a NaN then the general rules apply. 46660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Otherwise, the operands are compared as though by the compare 46670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operation. If they are numerically equal then the left-hand operand 46680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi is chosen as the result. Otherwise the maximum (closer to positive 46690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi infinity) of the two operands is chosen as the result. 46700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 46710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.max(Decimal('3'), Decimal('2')) 46720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3') 46730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.max(Decimal('-10'), Decimal('3')) 46740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3') 46750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.max(Decimal('1.0'), Decimal('1')) 46760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 46770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.max(Decimal('7'), Decimal('NaN')) 46780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('7') 46790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.max(1, 2) 46800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2') 46810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.max(Decimal(1), 2) 46820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2') 46830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.max(1, Decimal(2)) 46840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2') 46850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 46860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 46870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.max(b, context=self) 46880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 46890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def max_mag(self, a, b): 46900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compares the values numerically with their sign ignored. 46910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 46920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.max_mag(Decimal('7'), Decimal('NaN')) 46930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('7') 46940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.max_mag(Decimal('7'), Decimal('-10')) 46950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-10') 46960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.max_mag(1, -2) 46970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-2') 46980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.max_mag(Decimal(1), -2) 46990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-2') 47000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.max_mag(1, Decimal(-2)) 47010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-2') 47020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 47030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 47040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.max_mag(b, context=self) 47050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 47060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def min(self, a, b): 47070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """min compares two values numerically and returns the minimum. 47080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 47090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If either operand is a NaN then the general rules apply. 47100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Otherwise, the operands are compared as though by the compare 47110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operation. If they are numerically equal then the left-hand operand 47120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi is chosen as the result. Otherwise the minimum (closer to negative 47130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi infinity) of the two operands is chosen as the result. 47140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 47150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.min(Decimal('3'), Decimal('2')) 47160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2') 47170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.min(Decimal('-10'), Decimal('3')) 47180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-10') 47190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.min(Decimal('1.0'), Decimal('1')) 47200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.0') 47210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.min(Decimal('7'), Decimal('NaN')) 47220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('7') 47230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.min(1, 2) 47240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 47250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.min(Decimal(1), 2) 47260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 47270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.min(1, Decimal(29)) 47280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 47290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 47300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 47310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.min(b, context=self) 47320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 47330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def min_mag(self, a, b): 47340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compares the values numerically with their sign ignored. 47350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 47360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.min_mag(Decimal('3'), Decimal('-2')) 47370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-2') 47380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.min_mag(Decimal('-3'), Decimal('NaN')) 47390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-3') 47400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.min_mag(1, -2) 47410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 47420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.min_mag(Decimal(1), -2) 47430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 47440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.min_mag(1, Decimal(-2)) 47450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 47460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 47470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 47480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.min_mag(b, context=self) 47490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 47500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def minus(self, a): 47510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Minus corresponds to unary prefix minus in Python. 47520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 47530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The operation is evaluated using the same rules as subtract; the 47540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operation minus(a) is calculated as subtract('0', a) where the '0' 47550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi has the same exponent as the operand. 47560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 47570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.minus(Decimal('1.3')) 47580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1.3') 47590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.minus(Decimal('-1.3')) 47600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.3') 47610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.minus(1) 47620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 47630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 47640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 47650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.__neg__(context=self) 47660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 47670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def multiply(self, a, b): 47680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """multiply multiplies two operands. 47690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 47700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If either operand is a special value then the general rules apply. 47710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Otherwise, the operands are multiplied together 47720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('long multiplication'), resulting in a number which may be as long as 47730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the sum of the lengths of the two operands. 47740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 47750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3')) 47760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3.60') 47770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.multiply(Decimal('7'), Decimal('3')) 47780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('21') 47790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8')) 47800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.72') 47810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0')) 47820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-0.0') 47830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321')) 47840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('4.28135971E+11') 47850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.multiply(7, 7) 47860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('49') 47870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.multiply(Decimal(7), 7) 47880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('49') 47890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.multiply(7, Decimal(7)) 47900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('49') 47910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 47920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 47930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r = a.__mul__(b, context=self) 47940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if r is NotImplemented: 47950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise TypeError("Unable to convert %s to Decimal" % b) 47960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 47970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return r 47980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 47990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def next_minus(self, a): 48000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the largest representable number smaller than a. 48010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 48020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c = ExtendedContext.copy() 48030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emin = -999 48040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emax = 999 48050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.next_minus(Decimal('1')) 48060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.999999999') 48070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_minus(Decimal('1E-1007')) 48080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0E-1007') 48090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.next_minus(Decimal('-1.00000003')) 48100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1.00000004') 48110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_minus(Decimal('Infinity')) 48120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('9.99999999E+999') 48130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_minus(1) 48140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.999999999') 48150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 48160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 48170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.next_minus(context=self) 48180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 48190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def next_plus(self, a): 48200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the smallest representable number larger than a. 48210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 48220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c = ExtendedContext.copy() 48230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emin = -999 48240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emax = 999 48250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.next_plus(Decimal('1')) 48260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.00000001') 48270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_plus(Decimal('-1E-1007')) 48280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-0E-1007') 48290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.next_plus(Decimal('-1.00000003')) 48300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1.00000002') 48310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_plus(Decimal('-Infinity')) 48320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-9.99999999E+999') 48330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_plus(1) 48340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.00000001') 48350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 48360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 48370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.next_plus(context=self) 48380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 48390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def next_toward(self, a, b): 48400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the number closest to a, in direction towards b. 48410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 48420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The result is the closest representable number from the first 48430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operand (but not the first operand) that is in the direction 48440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi towards the second operand, unless the operands have the same 48450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi value. 48460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 48470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c = ExtendedContext.copy() 48480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emin = -999 48490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emax = 999 48500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_toward(Decimal('1'), Decimal('2')) 48510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.00000001') 48520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_toward(Decimal('-1E-1007'), Decimal('1')) 48530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-0E-1007') 48540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_toward(Decimal('-1.00000003'), Decimal('0')) 48550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1.00000002') 48560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_toward(Decimal('1'), Decimal('0')) 48570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.999999999') 48580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_toward(Decimal('1E-1007'), Decimal('-100')) 48590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0E-1007') 48600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_toward(Decimal('-1.00000003'), Decimal('-10')) 48610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1.00000004') 48620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_toward(Decimal('0.00'), Decimal('-0.0000')) 48630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-0.00') 48640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_toward(0, 1) 48650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1E-1007') 48660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_toward(Decimal(0), 1) 48670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1E-1007') 48680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.next_toward(0, Decimal(1)) 48690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1E-1007') 48700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 48710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 48720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.next_toward(b, context=self) 48730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 48740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def normalize(self, a): 48750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """normalize reduces an operand to its simplest form. 48760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 48770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Essentially a plus operation with all trailing zeros removed from the 48780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result. 48790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 48800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.normalize(Decimal('2.1')) 48810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.1') 48820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.normalize(Decimal('-2.0')) 48830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-2') 48840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.normalize(Decimal('1.200')) 48850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.2') 48860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.normalize(Decimal('-120')) 48870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1.2E+2') 48880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.normalize(Decimal('120.00')) 48890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.2E+2') 48900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.normalize(Decimal('0.00')) 48910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 48920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.normalize(6) 48930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('6') 48940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 48950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 48960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.normalize(context=self) 48970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 48980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def number_class(self, a): 48990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns an indication of the class of the operand. 49000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 49010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The class is one of the following strings: 49020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi -sNaN 49030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi -NaN 49040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi -Infinity 49050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi -Normal 49060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi -Subnormal 49070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi -Zero 49080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi +Zero 49090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi +Subnormal 49100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi +Normal 49110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi +Infinity 49120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 49130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c = Context(ExtendedContext) 49140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emin = -999 49150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emax = 999 49160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.number_class(Decimal('Infinity')) 49170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '+Infinity' 49180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.number_class(Decimal('1E-10')) 49190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '+Normal' 49200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.number_class(Decimal('2.50')) 49210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '+Normal' 49220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.number_class(Decimal('0.1E-999')) 49230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '+Subnormal' 49240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.number_class(Decimal('0')) 49250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '+Zero' 49260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.number_class(Decimal('-0')) 49270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '-Zero' 49280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.number_class(Decimal('-0.1E-999')) 49290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '-Subnormal' 49300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.number_class(Decimal('-1E-10')) 49310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '-Normal' 49320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.number_class(Decimal('-2.50')) 49330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '-Normal' 49340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.number_class(Decimal('-Infinity')) 49350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '-Infinity' 49360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.number_class(Decimal('NaN')) 49370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'NaN' 49380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.number_class(Decimal('-NaN')) 49390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'NaN' 49400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.number_class(Decimal('sNaN')) 49410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'sNaN' 49420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.number_class(123) 49430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '+Normal' 49440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 49450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 49460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.number_class(context=self) 49470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 49480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def plus(self, a): 49490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Plus corresponds to unary prefix plus in Python. 49500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 49510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The operation is evaluated using the same rules as add; the 49520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operation plus(a) is calculated as add('0', a) where the '0' 49530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi has the same exponent as the operand. 49540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 49550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.plus(Decimal('1.3')) 49560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.3') 49570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.plus(Decimal('-1.3')) 49580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1.3') 49590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.plus(-1) 49600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 49610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 49620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 49630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.__pos__(context=self) 49640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 49650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def power(self, a, b, modulo=None): 49660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Raises a to the power of b, to modulo if given. 49670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 49680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi With two arguments, compute a**b. If a is negative then b 49690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi must be integral. The result will be inexact unless b is 49700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi integral and the result is finite and can be expressed exactly 49710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi in 'precision' digits. 49720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 49730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi With three arguments, compute (a**b) % modulo. For the 49740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi three argument form, the following restrictions on the 49750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi arguments hold: 49760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 49770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi - all three arguments must be integral 49780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi - b must be nonnegative 49790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi - at least one of a or b must be nonzero 49800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi - modulo must be nonzero and have at most 'precision' digits 49810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 49820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The result of pow(a, b, modulo) is identical to the result 49830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi that would be obtained by computing (a**b) % modulo with 49840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unbounded precision, but is computed more efficiently. It is 49850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi always exact. 49860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 49870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c = ExtendedContext.copy() 49880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emin = -999 49890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.Emax = 999 49900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('2'), Decimal('3')) 49910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('8') 49920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('-2'), Decimal('3')) 49930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-8') 49940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('2'), Decimal('-3')) 49950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.125') 49960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('1.7'), Decimal('8')) 49970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('69.7575744') 49980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('10'), Decimal('0.301029996')) 49990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.00000000') 50000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('Infinity'), Decimal('-1')) 50010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 50020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('Infinity'), Decimal('0')) 50030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 50040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('Infinity'), Decimal('1')) 50050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('Infinity') 50060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('-Infinity'), Decimal('-1')) 50070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-0') 50080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('-Infinity'), Decimal('0')) 50090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 50100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('-Infinity'), Decimal('1')) 50110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-Infinity') 50120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('-Infinity'), Decimal('2')) 50130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('Infinity') 50140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('0'), Decimal('0')) 50150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('NaN') 50160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 50170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('3'), Decimal('7'), Decimal('16')) 50180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('11') 50190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('-3'), Decimal('7'), Decimal('16')) 50200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-11') 50210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('-3'), Decimal('8'), Decimal('16')) 50220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 50230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('3'), Decimal('7'), Decimal('-16')) 50240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('11') 50250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('23E12345'), Decimal('67E189'), Decimal('123456789')) 50260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('11729830') 50270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('-0'), Decimal('17'), Decimal('1729')) 50280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-0') 50290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> c.power(Decimal('-23'), Decimal('0'), Decimal('65537')) 50300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 50310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.power(7, 7) 50320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('823543') 50330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.power(Decimal(7), 7) 50340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('823543') 50350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.power(7, Decimal(7), 2) 50360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 50370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 50380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 50390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r = a.__pow__(b, modulo, context=self) 50400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if r is NotImplemented: 50410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise TypeError("Unable to convert %s to Decimal" % b) 50420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 50430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return r 50440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 50450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def quantize(self, a, b): 50460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns a value equal to 'a' (rounded), having the exponent of 'b'. 50470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 50480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The coefficient of the result is derived from that of the left-hand 50490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operand. It may be rounded using the current rounding setting (if the 50500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exponent is being increased), multiplied by a positive power of ten (if 50510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the exponent is being decreased), or is unchanged (if the exponent is 50520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi already equal to that of the right-hand operand). 50530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 50540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Unlike other operations, if the length of the coefficient after the 50550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi quantize operation would be greater than precision then an Invalid 50560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operation condition is raised. This guarantees that, unless there is 50570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi an error condition, the exponent of the result of a quantize is always 50580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi equal to that of the right-hand operand. 50590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 50600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Also unlike other operations, quantize will never raise Underflow, even 50610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if the result is subnormal and inexact. 50620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 50630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001')) 50640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.170') 50650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01')) 50660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.17') 50670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1')) 50680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.2') 50690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0')) 50700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2') 50710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1')) 50720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0E+1') 50730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity')) 50740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-Infinity') 50750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity')) 50760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('NaN') 50770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1')) 50780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-0') 50790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5')) 50800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-0E+5') 50810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2')) 50820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('NaN') 50830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2')) 50840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('NaN') 50850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1')) 50860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('217.0') 50870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0')) 50880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('217') 50890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1')) 50900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.2E+2') 50910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2')) 50920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2E+2') 50930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(1, 2) 50940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 50950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(Decimal(1), 2) 50960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 50970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.quantize(1, Decimal(2)) 50980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 50990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 51000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 51010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.quantize(b, context=self) 51020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 51030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def radix(self): 51040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Just returns 10, as this is Decimal, :) 51050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 51060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.radix() 51070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('10') 51080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 51090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(10) 51100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 51110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def remainder(self, a, b): 51120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the remainder from integer division. 51130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 51140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The result is the residue of the dividend after the operation of 51150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi calculating integer division as described for divide-integer, rounded 51160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi to precision digits if necessary. The sign of the result, if 51170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi non-zero, is the same as that of the original dividend. 51180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 51190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This operation will fail under the same conditions as integer division 51200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (that is, if integer division on the same two operands would fail, the 51210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi remainder cannot be calculated). 51220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 51230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3')) 51240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.1') 51250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder(Decimal('10'), Decimal('3')) 51260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 51270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3')) 51280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 51290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1')) 51300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.2') 51310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3')) 51320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.1') 51330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3')) 51340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.0') 51350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder(22, 6) 51360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('4') 51370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder(Decimal(22), 6) 51380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('4') 51390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder(22, Decimal(6)) 51400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('4') 51410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 51420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 51430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r = a.__mod__(b, context=self) 51440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if r is NotImplemented: 51450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise TypeError("Unable to convert %s to Decimal" % b) 51460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 51470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return r 51480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 51490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def remainder_near(self, a, b): 51500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns to be "a - b * n", where n is the integer nearest the exact 51510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi value of "x / b" (if two integers are equally near then the even one 51520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi is chosen). If the result is equal to 0 then its sign will be the 51530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign of a. 51540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 51550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This operation will fail under the same conditions as integer division 51560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (that is, if integer division on the same two operands would fail, the 51570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi remainder cannot be calculated). 51580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 51590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3')) 51600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-0.9') 51610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6')) 51620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-2') 51630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3')) 51640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 51650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3')) 51660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-1') 51670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1')) 51680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.2') 51690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3')) 51700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.1') 51710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3')) 51720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-0.3') 51730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder_near(3, 11) 51740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3') 51750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder_near(Decimal(3), 11) 51760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3') 51770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.remainder_near(3, Decimal(11)) 51780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3') 51790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 51800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 51810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.remainder_near(b, context=self) 51820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 51830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def rotate(self, a, b): 51840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns a rotated copy of a, b times. 51850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 51860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The coefficient of the result is a rotated copy of the digits in 51870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the coefficient of the first operand. The number of places of 51880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rotation is taken from the absolute value of the second operand, 51890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi with the rotation being to the left if the second operand is 51900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi positive or to the right otherwise. 51910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 51920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.rotate(Decimal('34'), Decimal('8')) 51930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('400000003') 51940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.rotate(Decimal('12'), Decimal('9')) 51950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('12') 51960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('-2')) 51970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('891234567') 51980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('0')) 51990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('123456789') 52000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('+2')) 52010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('345678912') 52020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.rotate(1333333, 1) 52030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('13333330') 52040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.rotate(Decimal(1333333), 1) 52050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('13333330') 52060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.rotate(1333333, Decimal(1)) 52070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('13333330') 52080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 52090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 52100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.rotate(b, context=self) 52110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 52120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def same_quantum(self, a, b): 52130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns True if the two operands have the same exponent. 52140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 52150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The result is never affected by either the sign or the coefficient of 52160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi either operand. 52170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 52180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001')) 52190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 52200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01')) 52210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 52220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1')) 52230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi False 52240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf')) 52250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 52260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.same_quantum(10000, -1) 52270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 52280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.same_quantum(Decimal(10000), -1) 52290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 52300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.same_quantum(10000, Decimal(-1)) 52310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi True 52320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 52330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 52340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.same_quantum(b) 52350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 52360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def scaleb (self, a, b): 52370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns the first operand after adding the second value its exp. 52380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 52390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('-2')) 52400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.0750') 52410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('0')) 52420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('7.50') 52430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('3')) 52440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('7.50E+3') 52450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.scaleb(1, 4) 52460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1E+4') 52470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.scaleb(Decimal(1), 4) 52480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1E+4') 52490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.scaleb(1, Decimal(4)) 52500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1E+4') 52510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 52520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 52530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.scaleb(b, context=self) 52540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 52550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def shift(self, a, b): 52560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns a shifted copy of a, b times. 52570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 52580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The coefficient of the result is a shifted copy of the digits 52590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi in the coefficient of the first operand. The number of places 52600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi to shift is taken from the absolute value of the second operand, 52610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi with the shift being to the left if the second operand is 52620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi positive or to the right otherwise. Digits shifted into the 52630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coefficient are zeros. 52640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 52650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.shift(Decimal('34'), Decimal('8')) 52660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('400000000') 52670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.shift(Decimal('12'), Decimal('9')) 52680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 52690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.shift(Decimal('123456789'), Decimal('-2')) 52700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1234567') 52710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.shift(Decimal('123456789'), Decimal('0')) 52720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('123456789') 52730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.shift(Decimal('123456789'), Decimal('+2')) 52740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('345678900') 52750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.shift(88888888, 2) 52760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('888888800') 52770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.shift(Decimal(88888888), 2) 52780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('888888800') 52790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.shift(88888888, Decimal(2)) 52800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('888888800') 52810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 52820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 52830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.shift(b, context=self) 52840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 52850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def sqrt(self, a): 52860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Square root of a non-negative number to context precision. 52870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 52880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If the result must be inexact, it is rounded using the round-half-even 52890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi algorithm. 52900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 52910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.sqrt(Decimal('0')) 52920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0') 52930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.sqrt(Decimal('-0')) 52940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-0') 52950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.sqrt(Decimal('0.39')) 52960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.624499800') 52970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.sqrt(Decimal('100')) 52980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('10') 52990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.sqrt(Decimal('1')) 53000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1') 53010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.sqrt(Decimal('1.0')) 53020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.0') 53030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.sqrt(Decimal('1.00')) 53040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.0') 53050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.sqrt(Decimal('7')) 53060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2.64575131') 53070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.sqrt(Decimal('10')) 53080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3.16227766') 53090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.sqrt(2) 53100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.41421356') 53110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.prec 53120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9 53130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 53140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 53150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.sqrt(context=self) 53160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 53170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def subtract(self, a, b): 53180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return the difference between the two operands. 53190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 53200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07')) 53210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.23') 53220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30')) 53230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('0.00') 53240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07')) 53250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-0.77') 53260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.subtract(8, 5) 53270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3') 53280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.subtract(Decimal(8), 5) 53290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3') 53300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.subtract(8, Decimal(5)) 53310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('3') 53320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 53330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 53340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r = a.__sub__(b, context=self) 53350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if r is NotImplemented: 53360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise TypeError("Unable to convert %s to Decimal" % b) 53370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 53380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return r 53390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 53400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def to_eng_string(self, a): 53410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Converts a number to a string, using scientific notation. 53420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 53430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The operation is not affected by the context. 53440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 53450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 53460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.to_eng_string(context=self) 53470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 53480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def to_sci_string(self, a): 53490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Converts a number to a string, using scientific notation. 53500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 53510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The operation is not affected by the context. 53520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 53530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 53540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.__str__(context=self) 53550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 53560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def to_integral_exact(self, a): 53570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Rounds to an integer. 53580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 53590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi When the operand has a negative exponent, the result is the same 53600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi as using the quantize() operation using the given operand as the 53610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi left-hand-operand, 1E+0 as the right-hand-operand, and the precision 53620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi of the operand as the precision setting; Inexact and Rounded flags 53630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi are allowed in this operation. The rounding mode is taken from the 53640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi context. 53650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 53660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_exact(Decimal('2.1')) 53670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2') 53680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_exact(Decimal('100')) 53690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('100') 53700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_exact(Decimal('100.0')) 53710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('100') 53720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_exact(Decimal('101.5')) 53730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('102') 53740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_exact(Decimal('-101.5')) 53750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-102') 53760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_exact(Decimal('10E+5')) 53770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.0E+6') 53780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_exact(Decimal('7.89E+77')) 53790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('7.89E+77') 53800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_exact(Decimal('-Inf')) 53810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-Infinity') 53820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 53830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 53840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.to_integral_exact(context=self) 53850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 53860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def to_integral_value(self, a): 53870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Rounds to an integer. 53880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 53890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi When the operand has a negative exponent, the result is the same 53900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi as using the quantize() operation using the given operand as the 53910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi left-hand-operand, 1E+0 as the right-hand-operand, and the precision 53920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi of the operand as the precision setting, except that no flags will 53930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi be set. The rounding mode is taken from the context. 53940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 53950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_value(Decimal('2.1')) 53960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('2') 53970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_value(Decimal('100')) 53980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('100') 53990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_value(Decimal('100.0')) 54000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('100') 54010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_value(Decimal('101.5')) 54020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('102') 54030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_value(Decimal('-101.5')) 54040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-102') 54050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_value(Decimal('10E+5')) 54060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('1.0E+6') 54070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_value(Decimal('7.89E+77')) 54080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('7.89E+77') 54090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> ExtendedContext.to_integral_value(Decimal('-Inf')) 54100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal('-Infinity') 54110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 54120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = _convert_other(a, raiseit=True) 54130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a.to_integral_value(context=self) 54140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 54150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # the method name changed, but we provide also the old one, for compatibility 54160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi to_integral = to_integral_value 54170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 54180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass _WorkRep(object): 54190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __slots__ = ('sign','int','exp') 54200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # sign: 0 or 1 54210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # int: int or long 54220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exp: None, int, or string 54230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 54240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self, value=None): 54250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if value is None: 54260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.sign = None 54270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.int = 0 54280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.exp = None 54290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif isinstance(value, Decimal): 54300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.sign = value._sign 54310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.int = int(value._int) 54320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.exp = value._exp 54330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 54340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # assert isinstance(value, tuple) 54350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.sign = value[0] 54360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.int = value[1] 54370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.exp = value[2] 54380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 54390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __repr__(self): 54400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "(%r, %r, %r)" % (self.sign, self.int, self.exp) 54410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 54420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __str__ = __repr__ 54430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 54440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 54450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 54460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _normalize(op1, op2, prec = 0): 54470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Normalizes op1, op2 to have the same exp and length of coefficient. 54480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 54490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Done during addition. 54500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 54510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if op1.exp < op2.exp: 54520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi tmp = op2 54530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = op1 54540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 54550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi tmp = op1 54560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other = op2 54570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 54580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Let exp = min(tmp.exp - 1, tmp.adjusted() - precision - 1). 54590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Then adding 10**exp to tmp has the same effect (after rounding) 54600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # as adding any positive quantity smaller than 10**exp; similarly 54610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # for subtraction. So if other is smaller than 10**exp we replace 54620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # it with 10**exp. This avoids tmp.exp - other.exp getting too large. 54630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi tmp_len = len(str(tmp.int)) 54640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other_len = len(str(other.int)) 54650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp = tmp.exp + min(-1, tmp_len - prec - 2) 54660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if other_len + other.exp - 1 < exp: 54670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other.int = 1 54680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi other.exp = exp 54690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 54700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi tmp.int *= 10 ** (tmp.exp - other.exp) 54710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi tmp.exp = other.exp 54720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return op1, op2 54730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 54740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##### Integer arithmetic functions used by ln, log10, exp and __pow__ ##### 54750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 54760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# This function from Tim Peters was taken from here: 54770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# http://mail.python.org/pipermail/python-list/1999-July/007758.html 54780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# The correction being in the function definition is for speed, and 54790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# the whole function is not resolved with math.log because of avoiding 54800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# the use of floats. 54810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _nbits(n, correction = { 54820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '0': 4, '1': 3, '2': 2, '3': 2, 54830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '4': 1, '5': 1, '6': 1, '7': 1, 54840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '8': 0, '9': 0, 'a': 0, 'b': 0, 54850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'c': 0, 'd': 0, 'e': 0, 'f': 0}): 54860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Number of bits in binary representation of the positive integer n, 54870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi or 0 if n == 0. 54880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 54890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n < 0: 54900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("The argument to _nbits should be nonnegative.") 54910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi hex_n = "%x" % n 54920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 4*len(hex_n) - correction[hex_n[0]] 54930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 54940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _decimal_lshift_exact(n, e): 54950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ Given integers n and e, return n * 10**e if it's an integer, else None. 54960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 54970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The computation is designed to avoid computing large powers of 10 54980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unnecessarily. 54990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> _decimal_lshift_exact(3, 4) 55010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30000 55020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi >>> _decimal_lshift_exact(300, -999999999) # returns None 55030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 55050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n == 0: 55060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 0 55070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif e >= 0: 55080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return n * 10**e 55090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 55100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # val_n = largest power of 10 dividing n. 55110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi str_n = str(abs(n)) 55120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi val_n = len(str_n) - len(str_n.rstrip('0')) 55130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None if val_n < -e else n // 10**-e 55140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _sqrt_nearest(n, a): 55160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Closest integer to the square root of the positive integer n. a is 55170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi an initial approximation to the square root. Any positive integer 55180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi will do for a, but the closer a is to the square root of n the 55190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi faster convergence will be. 55200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 55220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n <= 0 or a <= 0: 55230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("Both arguments to _sqrt_nearest should be positive.") 55240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi b=0 55260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while a != b: 55270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi b, a = a, a--n//a>>1 55280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a 55290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _rshift_nearest(x, shift): 55310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Given an integer x and a nonnegative integer shift, return closest 55320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi integer to x / 2**shift; use round-to-even in case of a tie. 55330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 55350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi b, q = 1L << shift, x >> shift 55360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return q + (2*(x & (b-1)) + (q&1) > b) 55370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _div_nearest(a, b): 55390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Closest integer to a/b, a and b positive integers; rounds to even 55400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi in the case of a tie. 55410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 55430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi q, r = divmod(a, b) 55440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return q + (2*r + (q&1) > b) 55450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _ilog(x, M, L = 8): 55470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Integer approximation to M*log(x/M), with absolute error boundable 55480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi in terms only of x/M. 55490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Given positive integers x and M, return an integer approximation to 55510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi M * log(x/M). For L = 8 and 0.1 <= x/M <= 10 the difference 55520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi between the approximation and the exact result is at most 22. For 55530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi L = 8 and 1.0 <= x/M <= 10.0 the difference is at most 15. In 55540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi both cases these are upper bounds on the error; it will usually be 55550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi much smaller.""" 55560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # The basic algorithm is the following: let log1p be the function 55580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # log1p(x) = log(1+x). Then log(x/M) = log1p((x-M)/M). We use 55590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # the reduction 55600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 55610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # log1p(y) = 2*log1p(y/(1+sqrt(1+y))) 55620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 55630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # repeatedly until the argument to log1p is small (< 2**-L in 55640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # absolute value). For small y we can use the Taylor series 55650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # expansion 55660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 55670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # log1p(y) ~ y - y**2/2 + y**3/3 - ... - (-y)**T/T 55680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 55690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # truncating at T such that y**T is small enough. The whole 55700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # computation is carried out in a form of fixed-point arithmetic, 55710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # with a real number z being represented by an integer 55720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # approximation to z*M. To avoid loss of precision, the y below 55730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # is actually an integer approximation to 2**R*y*M, where R is the 55740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # number of reductions performed so far. 55750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi y = x-M 55770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # argument reduction; R = number of reductions performed 55780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi R = 0 55790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while (R <= L and long(abs(y)) << L-R >= M or 55800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi R > L and abs(y) >> R-L >= M): 55810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi y = _div_nearest(long(M*y) << 1, 55820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi M + _sqrt_nearest(M*(M+_rshift_nearest(y, R)), M)) 55830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi R += 1 55840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Taylor series with T terms 55860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi T = -int(-10*len(str(M))//(3*L)) 55870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi yshift = _rshift_nearest(y, R) 55880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi w = _div_nearest(M, T) 55890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for k in xrange(T-1, 0, -1): 55900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi w = _div_nearest(M, k) - _div_nearest(yshift*w, M) 55910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _div_nearest(w*y, M) 55930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _dlog10(c, e, p): 55950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Given integers c, e and p with c > 0, p >= 0, compute an integer 55960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi approximation to 10**p * log10(c*10**e), with an absolute error of 55970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi at most 1. Assumes that c*10**e is not exactly 1.""" 55980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 55990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # increase precision by 2; compensate for this by dividing 56000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # final result by 100 56010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p += 2 56020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 56030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # write c*10**e as d*10**f with either: 56040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # f >= 0 and 1 <= d <= 10, or 56050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # f <= 0 and 0.1 <= d <= 1. 56060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Thus for c*10**e close to 1, f = 0 56070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi l = len(str(c)) 56080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi f = e+l - (e+l >= 1) 56090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 56100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if p > 0: 56110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi M = 10**p 56120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi k = e+p-f 56130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if k >= 0: 56140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c *= 10**k 56150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 56160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = _div_nearest(c, 10**-k) 56170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 56180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi log_d = _ilog(c, M) # error < 5 + 22 = 27 56190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi log_10 = _log10_digits(p) # error < 1 56200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi log_d = _div_nearest(log_d*M, log_10) 56210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi log_tenpower = f*M # exact 56220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 56230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi log_d = 0 # error < 2.31 56240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi log_tenpower = _div_nearest(f, 10**-p) # error < 0.5 56250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 56260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _div_nearest(log_tenpower+log_d, 100) 56270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 56280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _dlog(c, e, p): 56290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Given integers c, e and p with c > 0, compute an integer 56300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi approximation to 10**p * log(c*10**e), with an absolute error of 56310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi at most 1. Assumes that c*10**e is not exactly 1.""" 56320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 56330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Increase precision by 2. The precision increase is compensated 56340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # for at the end with a division by 100. 56350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p += 2 56360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 56370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # rewrite c*10**e as d*10**f with either f >= 0 and 1 <= d <= 10, 56380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # or f <= 0 and 0.1 <= d <= 1. Then we can compute 10**p * log(c*10**e) 56390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # as 10**p * log(d) + 10**p*f * log(10). 56400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi l = len(str(c)) 56410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi f = e+l - (e+l >= 1) 56420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 56430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute approximation to 10**p*log(d), with error < 27 56440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if p > 0: 56450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi k = e+p-f 56460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if k >= 0: 56470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c *= 10**k 56480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 56490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = _div_nearest(c, 10**-k) # error of <= 0.5 in c 56500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 56510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # _ilog magnifies existing error in c by a factor of at most 10 56520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi log_d = _ilog(c, 10**p) # error < 5 + 22 = 27 56530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 56540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # p <= 0: just approximate the whole thing by 0; error < 2.31 56550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi log_d = 0 56560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 56570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute approximation to f*10**p*log(10), with error < 11. 56580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if f: 56590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi extra = len(str(abs(f)))-1 56600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if p + extra >= 0: 56610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # error in f * _log10_digits(p+extra) < |f| * 1 = |f| 56620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # after division, error < |f|/10**extra + 0.5 < 10 + 0.5 < 11 56630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi f_log_ten = _div_nearest(f*_log10_digits(p+extra), 10**extra) 56640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 56650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi f_log_ten = 0 56660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 56670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi f_log_ten = 0 56680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 56690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # error in sum < 11+27 = 38; error after division < 0.38 + 0.5 < 1 56700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _div_nearest(f_log_ten + log_d, 100) 56710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 56720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass _Log10Memoize(object): 56730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Class to compute, store, and allow retrieval of, digits of the 56740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi constant log(10) = 2.302585.... This constant is needed by 56750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Decimal.ln, Decimal.log10, Decimal.exp and Decimal.__pow__.""" 56760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self): 56770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.digits = "23025850929940456840179914546843642076011014886" 56780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 56790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getdigits(self, p): 56800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Given an integer p >= 0, return floor(10**p)*log(10). 56810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 56820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi For example, self.getdigits(3) returns 2302. 56830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 56840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # digits are stored as a string, for quick conversion to 56850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # integer in the case that we've already computed enough 56860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # digits; the stored digits should always be correct 56870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # (truncated, not rounded to nearest). 56880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if p < 0: 56890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("p should be nonnegative") 56900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 56910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if p >= len(self.digits): 56920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute p+3, p+6, p+9, ... digits; continue until at 56930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # least one of the extra digits is nonzero 56940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi extra = 3 56950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while True: 56960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute p+extra digits, correct to within 1ulp 56970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi M = 10**(p+extra+2) 56980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi digits = str(_div_nearest(_ilog(10*M, M), 100)) 56990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if digits[-extra:] != '0'*extra: 57000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 57010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi extra += 3 57020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # keep all reliable digits so far; remove trailing zeros 57030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # and next nonzero digit 57040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.digits = digits.rstrip('0')[:-1] 57050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return int(self.digits[:p+1]) 57060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_log10_digits = _Log10Memoize().getdigits 57080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _iexp(x, M, L=8): 57100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Given integers x and M, M > 0, such that x/M is small in absolute 57110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi value, compute an integer approximation to M*exp(x/M). For 0 <= 57120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi x/M <= 2.4, the absolute error in the result is bounded by 60 (and 57130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi is usually much smaller).""" 57140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Algorithm: to compute exp(z) for a real number z, first divide z 57160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # by a suitable power R of 2 so that |z/2**R| < 2**-L. Then 57170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute expm1(z/2**R) = exp(z/2**R) - 1 using the usual Taylor 57180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # series 57190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 57200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # expm1(x) = x + x**2/2! + x**3/3! + ... 57210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 57220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Now use the identity 57230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 57240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # expm1(2x) = expm1(x)*(expm1(x)+2) 57250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 57260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # R times to compute the sequence expm1(z/2**R), 57270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # expm1(z/2**(R-1)), ... , exp(z/2), exp(z). 57280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Find R such that x/2**R/M <= 2**-L 57300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi R = _nbits((long(x)<<L)//M) 57310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Taylor series. (2**L)**T > M 57330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi T = -int(-10*len(str(M))//(3*L)) 57340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi y = _div_nearest(x, T) 57350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Mshift = long(M)<<R 57360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for i in xrange(T-1, 0, -1): 57370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi y = _div_nearest(x*(Mshift + y), Mshift * i) 57380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Expansion 57400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for k in xrange(R-1, -1, -1): 57410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Mshift = long(M)<<(k+2) 57420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi y = _div_nearest(y*(y+Mshift), Mshift) 57430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return M+y 57450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _dexp(c, e, p): 57470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compute an approximation to exp(c*10**e), with p decimal places of 57480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi precision. 57490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Returns integers d, f such that: 57510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10**(p-1) <= d <= 10**p, and 57530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (d-1)*10**f < exp(c*10**e) < (d+1)*10**f 57540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi In other words, d*10**f is an approximation to exp(c*10**e) with p 57560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi digits of precision, and with an error in d of at most 1. This is 57570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi almost, but not quite, the same as the error being < 1ulp: when d 57580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi = 10**(p-1) the error could be up to 10 ulp.""" 57590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # we'll call iexp with M = 10**(p+2), giving p+3 digits of precision 57610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p += 2 57620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute log(10) with extra precision = adjusted exponent of c*10**e 57640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi extra = max(0, e + len(str(c)) - 1) 57650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi q = p + extra 57660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute quotient c*10**e/(log(10)) = c*10**(e+q)/(log(10)*10**q), 57680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # rounding down 57690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi shift = e+q 57700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if shift >= 0: 57710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi cshift = c*10**shift 57720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 57730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi cshift = c//10**-shift 57740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi quot, rem = divmod(cshift, _log10_digits(q)) 57750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # reduce remainder back to original precision 57770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rem = _div_nearest(rem, 10**extra) 57780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # error in result of _iexp < 120; error after division < 0.62 57800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _div_nearest(_iexp(rem, 10**p), 1000), quot - p + 3 57810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _dpower(xc, xe, yc, ye, p): 57830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Given integers xc, xe, yc and ye representing Decimals x = xc*10**xe and 57840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi y = yc*10**ye, compute x**y. Returns a pair of integers (c, e) such that: 57850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10**(p-1) <= c <= 10**p, and 57870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (c-1)*10**e < x**y < (c+1)*10**e 57880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi in other words, c*10**e is an approximation to x**y with p digits 57900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi of precision, and with an error in c of at most 1. (This is 57910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi almost, but not quite, the same as the error being < 1ulp: when c 57920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi == 10**(p-1) we can only guarantee error < 10ulp.) 57930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi We assume that: x is positive and not equal to 1, and y is nonzero. 57950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 57960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 57970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Find b such that 10**(b-1) <= |y| <= 10**b 57980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi b = len(str(abs(yc))) + ye 57990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # log(x) = lxc*10**(-p-b-1), to p+b+1 places after the decimal point 58010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi lxc = _dlog(xc, xe, p+b+1) 58020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # compute product y*log(x) = yc*lxc*10**(-p-b-1+ye) = pc*10**(-p-1) 58040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi shift = ye-b 58050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if shift >= 0: 58060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pc = lxc*yc*10**shift 58070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 58080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pc = _div_nearest(lxc*yc, 10**-shift) 58090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if pc == 0: 58110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # we prefer a result that isn't exactly 1; this makes it 58120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # easier to compute a correctly rounded result in __pow__ 58130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ((len(str(xc)) + xe >= 1) == (yc > 0)): # if x**y > 1: 58140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff, exp = 10**(p-1)+1, 1-p 58150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 58160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff, exp = 10**p-1, -p 58170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 58180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff, exp = _dexp(pc, -(p+1), p+1) 58190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi coeff = _div_nearest(coeff, 10) 58200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp += 1 58210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return coeff, exp 58230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _log10_lb(c, correction = { 58250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '1': 100, '2': 70, '3': 53, '4': 40, '5': 31, 58260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '6': 23, '7': 16, '8': 10, '9': 5}): 58270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Compute a lower bound for 100*log10(c) for a positive integer c.""" 58280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if c <= 0: 58290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("The argument to _log10_lb should be nonnegative.") 58300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi str_c = str(c) 58310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 100*len(str_c) - correction[str_c[0]] 58320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##### Helper Functions #################################################### 58340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _convert_other(other, raiseit=False, allow_float=False): 58360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Convert other to Decimal. 58370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Verifies that it's ok to use in an implicit construction. 58390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If allow_float is true, allow conversion from float; this 58400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi is used in the comparison methods (__eq__ and friends). 58410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 58430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(other, Decimal): 58440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return other 58450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(other, (int, long)): 58460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal(other) 58470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if allow_float and isinstance(other, float): 58480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Decimal.from_float(other) 58490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if raiseit: 58510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise TypeError("Unable to convert %s to Decimal" % other) 58520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return NotImplemented 58530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##### Setup Specific Contexts ############################################ 58550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# The default context prototype used by Context() 58570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Is mutable, so that new contexts can have different default values 58580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDefaultContext = Context( 58600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi prec=28, rounding=ROUND_HALF_EVEN, 58610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi traps=[DivisionByZero, Overflow, InvalidOperation], 58620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi flags=[], 58630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Emax=999999999, 58640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Emin=-999999999, 58650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi capitals=1 58660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi) 58670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Pre-made alternate contexts offered by the specification 58690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Don't change these; the user should be able to select these 58700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# contexts and be able to reproduce results from other implementations 58710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# of the spec. 58720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiBasicContext = Context( 58740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi prec=9, rounding=ROUND_HALF_UP, 58750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow], 58760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi flags=[], 58770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi) 58780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiExtendedContext = Context( 58800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi prec=9, rounding=ROUND_HALF_EVEN, 58810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi traps=[], 58820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi flags=[], 58830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi) 58840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 58860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##### crud for parsing strings ############################################# 58870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# 58880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Regular expression used for parsing numeric strings. Additional 58890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# comments: 58900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# 58910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# 1. Uncomment the two '\s*' lines to allow leading and/or trailing 58920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# whitespace. But note that the specification disallows whitespace in 58930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# a numeric string. 58940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# 58950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# 2. For finite numbers (not infinities and NaNs) the body of the 58960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# number between the optional sign and the optional exponent must have 58970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# at least one decimal digit, possibly after the decimal point. The 58980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# lookahead expression '(?=\d|\.\d)' checks this. 58990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 59000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport re 59010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_parser = re.compile(r""" # A numeric string consists of: 59020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# \s* 59030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (?P<sign>[-+])? # an optional sign, followed by either... 59040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ( 59050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (?=\d|\.\d) # ...a number (with at least one digit) 59060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (?P<int>\d*) # having a (possibly empty) integer part 59070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (\.(?P<frac>\d*))? # followed by an optional fractional part 59080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (E(?P<exp>[-+]?\d+))? # followed by an optional exponent, or... 59090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi | 59100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Inf(inity)? # ...an infinity, or... 59110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi | 59120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (?P<signal>s)? # ...an (optionally signaling) 59130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi NaN # NaN 59140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (?P<diag>\d*) # with (possibly empty) diagnostic info. 59150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ) 59160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# \s* 59170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi \Z 59180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""", re.VERBOSE | re.IGNORECASE | re.UNICODE).match 59190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 59200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_all_zeros = re.compile('0*$').match 59210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_exact_half = re.compile('50*$').match 59220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 59230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##### PEP3101 support functions ############################################## 59240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# The functions in this section have little to do with the Decimal 59250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# class, and could potentially be reused or adapted for other pure 59260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Python numeric classes that want to implement __format__ 59270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# 59280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# A format specifier for Decimal looks like: 59290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# 59300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# [[fill]align][sign][0][minimumwidth][,][.precision][type] 59310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 59320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_parse_format_specifier_regex = re.compile(r"""\A 59330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi(?: 59340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (?P<fill>.)? 59350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (?P<align>[<>=^]) 59360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi)? 59370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi(?P<sign>[-+ ])? 59380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi(?P<zeropad>0)? 59390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi(?P<minimumwidth>(?!0)\d+)? 59400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi(?P<thousands_sep>,)? 59410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi(?:\.(?P<precision>0|(?!0)\d+))? 59420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi(?P<type>[eEfFgGn%])? 59430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\Z 59440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""", re.VERBOSE) 59450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 59460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidel re 59470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 59480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# The locale module is only needed for the 'n' format specifier. The 59490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# rest of the PEP 3101 code functions quite happily without it, so we 59500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# don't care too much if locale isn't present. 59510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yitry: 59520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi import locale as _locale 59530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiexcept ImportError: 59540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pass 59550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 59560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _parse_format_specifier(format_spec, _localeconv=None): 59570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Parse and validate a format specifier. 59580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 59590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Turns a standard numeric format specifier into a dict, with the 59600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi following entries: 59610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 59620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fill: fill character to pad field to minimum width 59630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi align: alignment type, either '<', '>', '=' or '^' 59640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign: either '+', '-' or ' ' 59650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi minimumwidth: nonnegative integer giving minimum width 59660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi zeropad: boolean, indicating whether to pad with zeros 59670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi thousands_sep: string to use as thousands separator, or '' 59680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi grouping: grouping for thousands separators, in format 59690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi used by localeconv 59700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi decimal_point: string to use for decimal point 59710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi precision: nonnegative integer giving precision, or None 59720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi type: one of the characters 'eEfFgG%', or None 59730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unicode: boolean (always True for Python 3.x) 59740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 59750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 59760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = _parse_format_specifier_regex.match(format_spec) 59770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if m is None: 59780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("Invalid format specifier: " + format_spec) 59790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 59800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # get the dictionary 59810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict = m.groupdict() 59820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 59830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # zeropad; defaults for fill and alignment. If zero padding 59840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # is requested, the fill and align fields should be absent. 59850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fill = format_dict['fill'] 59860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi align = format_dict['align'] 59870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict['zeropad'] = (format_dict['zeropad'] is not None) 59880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if format_dict['zeropad']: 59890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if fill is not None: 59900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("Fill character conflicts with '0'" 59910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi " in format specifier: " + format_spec) 59920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if align is not None: 59930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("Alignment conflicts with '0' in " 59940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "format specifier: " + format_spec) 59950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict['fill'] = fill or ' ' 59960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # PEP 3101 originally specified that the default alignment should 59970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # be left; it was later agreed that right-aligned makes more sense 59980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # for numeric types. See http://bugs.python.org/issue6857. 59990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict['align'] = align or '>' 60000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # default sign handling: '-' for negative, '' for positive 60020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if format_dict['sign'] is None: 60030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict['sign'] = '-' 60040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # minimumwidth defaults to 0; precision remains None if not given 60060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict['minimumwidth'] = int(format_dict['minimumwidth'] or '0') 60070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if format_dict['precision'] is not None: 60080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict['precision'] = int(format_dict['precision']) 60090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if format type is 'g' or 'G' then a precision of 0 makes little 60110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # sense; convert it to 1. Same if format type is unspecified. 60120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if format_dict['precision'] == 0: 60130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if format_dict['type'] is None or format_dict['type'] in 'gG': 60140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict['precision'] = 1 60150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # determine thousands separator, grouping, and decimal separator, and 60170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # add appropriate entries to format_dict 60180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if format_dict['type'] == 'n': 60190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # apart from separators, 'n' behaves just like 'g' 60200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict['type'] = 'g' 60210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if _localeconv is None: 60220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _localeconv = _locale.localeconv() 60230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if format_dict['thousands_sep'] is not None: 60240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("Explicit thousands separator conflicts with " 60250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "'n' type in format specifier: " + format_spec) 60260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict['thousands_sep'] = _localeconv['thousands_sep'] 60270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict['grouping'] = _localeconv['grouping'] 60280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict['decimal_point'] = _localeconv['decimal_point'] 60290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 60300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if format_dict['thousands_sep'] is None: 60310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict['thousands_sep'] = '' 60320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict['grouping'] = [3, 0] 60330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict['decimal_point'] = '.' 60340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # record whether return type should be str or unicode 60360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format_dict['unicode'] = isinstance(format_spec, unicode) 60370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return format_dict 60390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _format_align(sign, body, spec): 60410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Given an unpadded, non-aligned numeric string 'body' and sign 60420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi string 'sign', add padding and alignment conforming to the given 60430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format specifier dictionary 'spec' (as produced by 60440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi parse_format_specifier). 60450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Also converts result to unicode if necessary. 60470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 60490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # how much extra space do we have to play with? 60500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi minimumwidth = spec['minimumwidth'] 60510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fill = spec['fill'] 60520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi padding = fill*(minimumwidth - len(sign) - len(body)) 60530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi align = spec['align'] 60550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if align == '<': 60560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result = sign + body + padding 60570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif align == '>': 60580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result = padding + sign + body 60590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif align == '=': 60600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result = sign + padding + body 60610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif align == '^': 60620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi half = len(padding)//2 60630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result = padding[:half] + sign + body + padding[half:] 60640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 60650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError('Unrecognised alignment field') 60660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # make sure that result is unicode if necessary 60680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if spec['unicode']: 60690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result = unicode(result) 60700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return result 60720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _group_lengths(grouping): 60740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Convert a localeconv-style grouping into a (possibly infinite) 60750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi iterable of integers representing group lengths. 60760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 60780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # The result from localeconv()['grouping'], and the input to this 60790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # function, should be a list of integers in one of the 60800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # following three forms: 60810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 60820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # (1) an empty list, or 60830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # (2) nonempty list of positive integers + [0] 60840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # (3) list of positive integers + [locale.CHAR_MAX], or 60850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi from itertools import chain, repeat 60870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not grouping: 60880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return [] 60890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif grouping[-1] == 0 and len(grouping) >= 2: 60900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return chain(grouping[:-1], repeat(grouping[-2])) 60910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif grouping[-1] == _locale.CHAR_MAX: 60920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return grouping[:-1] 60930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 60940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError('unrecognised format for grouping') 60950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _insert_thousands_sep(digits, spec, min_width=1): 60970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Insert thousands separators into a digit string. 60980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 60990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi spec is a dictionary whose keys should include 'thousands_sep' and 61000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'grouping'; typically it's the result of parsing the format 61010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi specifier using _parse_format_specifier. 61020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The min_width keyword argument gives the minimum length of the 61040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result, which will be padded on the left with zeros if necessary. 61050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If necessary, the zero padding adds an extra '0' on the left to 61070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi avoid a leading thousands separator. For example, inserting 61080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi commas every three digits in '123456', with min_width=8, gives 61090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '0,123,456', even though that has length 9. 61100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 61120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sep = spec['thousands_sep'] 61140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi grouping = spec['grouping'] 61150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi groups = [] 61170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for l in _group_lengths(grouping): 61180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if l <= 0: 61190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("group length should be positive") 61200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # max(..., 1) forces at least 1 digit to the left of a separator 61210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi l = min(max(len(digits), min_width, 1), l) 61220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi groups.append('0'*(l - len(digits)) + digits[-l:]) 61230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi digits = digits[:-l] 61240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi min_width -= l 61250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not digits and min_width <= 0: 61260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 61270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi min_width -= len(sep) 61280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 61290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi l = max(len(digits), min_width, 1) 61300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi groups.append('0'*(l - len(digits)) + digits[-l:]) 61310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return sep.join(reversed(groups)) 61320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _format_sign(is_negative, spec): 61340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Determine sign character.""" 61350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if is_negative: 61370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return '-' 61380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif spec['sign'] in ' +': 61390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return spec['sign'] 61400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 61410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return '' 61420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _format_number(is_negative, intpart, fracpart, exp, spec): 61440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Format a number, given the following data: 61450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi is_negative: true if the number is negative, else false 61470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi intpart: string of digits that must appear before the decimal point 61480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fracpart: string of digits that must come after the point 61490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi exp: exponent, as an integer 61500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi spec: dictionary resulting from parsing the format specifier 61510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This function uses the information in spec to: 61530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi insert separators (decimal separator and thousands separators) 61540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format the sign 61550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi format the exponent 61560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi add trailing '%' for the '%' type 61570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi zero-pad if necessary 61580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fill and align if necessary 61590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 61600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = _format_sign(is_negative, spec) 61620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if fracpart: 61640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fracpart = spec['decimal_point'] + fracpart 61650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if exp != 0 or spec['type'] in 'eE': 61670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi echar = {'E': 'E', 'e': 'e', 'G': 'E', 'g': 'e'}[spec['type']] 61680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fracpart += "{0}{1:+}".format(echar, exp) 61690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if spec['type'] == '%': 61700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fracpart += '%' 61710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if spec['zeropad']: 61730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi min_width = spec['minimumwidth'] - len(fracpart) - len(sign) 61740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 61750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi min_width = 0 61760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi intpart = _insert_thousands_sep(intpart, spec, min_width) 61770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _format_align(sign, intpart+fracpart, spec) 61790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##### Useful Constants (internal use only) ################################ 61820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Reusable defaults 61840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_Infinity = Decimal('Inf') 61850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_NegativeInfinity = Decimal('-Inf') 61860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_NaN = Decimal('NaN') 61870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_Zero = Decimal(0) 61880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_One = Decimal(1) 61890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_NegativeOne = Decimal(-1) 61900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# _SignedInfinity[sign] is infinity w/ that sign 61920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_SignedInfinity = (_Infinity, _NegativeInfinity) 61930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 61960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiif __name__ == '__main__': 61970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi import doctest, sys 61980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doctest.testmod(sys.modules[__name__]) 6199