Changeset 388 for python/vendor/current/Lib/decimal.py
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Lib/decimal.py
r2 r388 22 22 the General Decimal Arithmetic Specification: 23 23 24 www2.hursley.ibm.com/decimal/decarith.html24 http://speleotrove.com/decimal/decarith.html 25 25 26 26 and IEEE standard 854-1987: 27 27 28 www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html28 http://en.wikipedia.org/wiki/IEEE_854-1987 29 29 30 30 Decimal floating point has finite precision with arbitrarily large bounds. … … 135 135 ] 136 136 137 __version__ = '1.70' # Highest version of the spec this complies with 138 137 139 import copy as _copy 140 import math as _math 138 141 import numbers as _numbers 139 142 … … 166 169 167 170 handle -- Called when context._raise_error is called and the 168 trap_enabler is set. First argument is self, second is the171 trap_enabler is not set. First argument is self, second is the 169 172 context. More arguments can be given, those being after 170 173 the explanation in _raise_error (For example, … … 646 649 647 650 if isinstance(value, float): 648 raise TypeError("Cannot convert float to Decimal. " + 649 "First convert the float to a string") 651 value = Decimal.from_float(value) 652 self._exp = value._exp 653 self._sign = value._sign 654 self._int = value._int 655 self._is_special = value._is_special 656 return self 650 657 651 658 raise TypeError("Cannot convert %r to Decimal" % value) 659 660 # @classmethod, but @decorator is not valid Python 2.3 syntax, so 661 # don't use it (see notes on Py2.3 compatibility at top of file) 662 def from_float(cls, f): 663 """Converts a float to a decimal number, exactly. 664 665 Note that Decimal.from_float(0.1) is not the same as Decimal('0.1'). 666 Since 0.1 is not exactly representable in binary floating point, the 667 value is stored as the nearest representable value which is 668 0x1.999999999999ap-4. The exact equivalent of the value in decimal 669 is 0.1000000000000000055511151231257827021181583404541015625. 670 671 >>> Decimal.from_float(0.1) 672 Decimal('0.1000000000000000055511151231257827021181583404541015625') 673 >>> Decimal.from_float(float('nan')) 674 Decimal('NaN') 675 >>> Decimal.from_float(float('inf')) 676 Decimal('Infinity') 677 >>> Decimal.from_float(-float('inf')) 678 Decimal('-Infinity') 679 >>> Decimal.from_float(-0.0) 680 Decimal('-0') 681 682 """ 683 if isinstance(f, (int, long)): # handle integer inputs 684 return cls(f) 685 if _math.isinf(f) or _math.isnan(f): # raises TypeError if not a float 686 return cls(repr(f)) 687 if _math.copysign(1.0, f) == 1.0: 688 sign = 0 689 else: 690 sign = 1 691 n, d = abs(f).as_integer_ratio() 692 k = d.bit_length() - 1 693 result = _dec_from_triple(sign, str(n*5**k), -k) 694 if cls is Decimal: 695 return result 696 else: 697 return cls(result) 698 from_float = classmethod(from_float) 652 699 653 700 def _isnan(self): … … 803 850 # We take the following approach: 804 851 # 805 # == comparisons involving a NaN always return False 806 # != comparisons involving a NaN always return True 852 # == comparisons involving a quiet NaN always return False 853 # != comparisons involving a quiet NaN always return True 854 # == or != comparisons involving a signaling NaN signal 855 # InvalidOperation, and return False or True as above if the 856 # InvalidOperation is not trapped. 807 857 # <, >, <= and >= comparisons involving a (quiet or signaling) 808 858 # NaN signal InvalidOperation, and return False if the … … 812 862 # that specified by IEEE 754. 813 863 814 def __eq__(self, other ):815 other = _convert_other(other )864 def __eq__(self, other, context=None): 865 other = _convert_other(other, allow_float=True) 816 866 if other is NotImplemented: 817 867 return other 818 if self. is_nan() or other.is_nan():868 if self._check_nans(other, context): 819 869 return False 820 870 return self._cmp(other) == 0 821 871 822 def __ne__(self, other ):823 other = _convert_other(other )872 def __ne__(self, other, context=None): 873 other = _convert_other(other, allow_float=True) 824 874 if other is NotImplemented: 825 875 return other 826 if self. is_nan() or other.is_nan():876 if self._check_nans(other, context): 827 877 return True 828 878 return self._cmp(other) != 0 829 879 830 880 def __lt__(self, other, context=None): 831 other = _convert_other(other )881 other = _convert_other(other, allow_float=True) 832 882 if other is NotImplemented: 833 883 return other … … 838 888 839 889 def __le__(self, other, context=None): 840 other = _convert_other(other )890 other = _convert_other(other, allow_float=True) 841 891 if other is NotImplemented: 842 892 return other … … 847 897 848 898 def __gt__(self, other, context=None): 849 other = _convert_other(other )899 other = _convert_other(other, allow_float=True) 850 900 if other is NotImplemented: 851 901 return other … … 856 906 857 907 def __ge__(self, other, context=None): 858 other = _convert_other(other )908 other = _convert_other(other, allow_float=True) 859 909 if other is NotImplemented: 860 910 return other … … 890 940 # on the value of that Decimal, and not on its representation. 891 941 # For example: hash(Decimal('100E-1')) == hash(Decimal('10')). 942 943 # Equality comparisons involving signaling nans can raise an 944 # exception; since equality checks are implicitly and 945 # unpredictably used when checking set and dict membership, we 946 # prevent signaling nans from being used as set elements or 947 # dict keys by making __hash__ raise an exception. 892 948 if self._is_special: 893 if self._isnan(): 894 raise TypeError('Cannot hash a NaN value.') 895 return hash(str(self)) 896 if not self: 897 return 0 949 if self.is_snan(): 950 raise TypeError('Cannot hash a signaling NaN value.') 951 elif self.is_nan(): 952 # 0 to match hash(float('nan')) 953 return 0 954 else: 955 # values chosen to match hash(float('inf')) and 956 # hash(float('-inf')). 957 if self._sign: 958 return -271828 959 else: 960 return 314159 961 962 # In Python 2.7, we're allowing comparisons (but not 963 # arithmetic operations) between floats and Decimals; so if 964 # a Decimal instance is exactly representable as a float then 965 # its hash should match that of the float. 966 self_as_float = float(self) 967 if Decimal.from_float(self_as_float) == self: 968 return hash(self_as_float) 969 898 970 if self._isinteger(): 899 971 op = _WorkRep(self.to_integral_value()) … … 997 1069 return ans 998 1070 999 if not self: 1000 # -Decimal('0') is Decimal('0'), not Decimal('-0') 1071 if context is None: 1072 context = getcontext() 1073 1074 if not self and context.rounding != ROUND_FLOOR: 1075 # -Decimal('0') is Decimal('0'), not Decimal('-0'), except 1076 # in ROUND_FLOOR rounding mode. 1001 1077 ans = self.copy_abs() 1002 1078 else: 1003 1079 ans = self.copy_negate() 1004 1080 1005 if context is None:1006 context = getcontext()1007 1081 return ans._fix(context) 1008 1082 … … 1017 1091 return ans 1018 1092 1019 if not self: 1020 # + (-0) = 0 1093 if context is None: 1094 context = getcontext() 1095 1096 if not self and context.rounding != ROUND_FLOOR: 1097 # + (-0) = 0, except in ROUND_FLOOR rounding mode. 1021 1098 ans = self.copy_abs() 1022 1099 else: 1023 1100 ans = Decimal(self) 1024 1101 1025 if context is None:1026 context = getcontext()1027 1102 return ans._fix(context) 1028 1103 … … 1507 1582 def __float__(self): 1508 1583 """Float representation.""" 1509 return float(str(self)) 1584 if self._isnan(): 1585 if self.is_snan(): 1586 raise ValueError("Cannot convert signaling NaN to float") 1587 s = "-nan" if self._sign else "nan" 1588 else: 1589 s = str(self) 1590 return float(s) 1510 1591 1511 1592 def __int__(self): … … 1593 1674 if exp_min > Etop: 1594 1675 # overflow: exp_min > Etop iff self.adjusted() > Emax 1676 ans = context._raise_error(Overflow, 'above Emax', self._sign) 1595 1677 context._raise_error(Inexact) 1596 1678 context._raise_error(Rounded) 1597 return context._raise_error(Overflow, 'above Emax', self._sign) 1679 return ans 1680 1598 1681 self_is_subnormal = exp_min < Etiny 1599 1682 if self_is_subnormal: 1600 context._raise_error(Subnormal)1601 1683 exp_min = Etiny 1602 1684 1603 1685 # round if self has too many digits 1604 1686 if self._exp < exp_min: 1605 context._raise_error(Rounded)1606 1687 digits = len(self._int) + self._exp - exp_min 1607 1688 if digits < 0: 1608 1689 self = _dec_from_triple(self._sign, '1', exp_min-1) 1609 1690 digits = 0 1610 this_function = getattr(self, self._pick_rounding_function[context.rounding])1611 changed = this_function(digits)1691 rounding_method = self._pick_rounding_function[context.rounding] 1692 changed = rounding_method(self, digits) 1612 1693 coeff = self._int[:digits] or '0' 1613 if changed == 1:1694 if changed > 0: 1614 1695 coeff = str(int(coeff)+1) 1615 ans = _dec_from_triple(self._sign, coeff, exp_min) 1616 1696 if len(coeff) > context.prec: 1697 coeff = coeff[:-1] 1698 exp_min += 1 1699 1700 # check whether the rounding pushed the exponent out of range 1701 if exp_min > Etop: 1702 ans = context._raise_error(Overflow, 'above Emax', self._sign) 1703 else: 1704 ans = _dec_from_triple(self._sign, coeff, exp_min) 1705 1706 # raise the appropriate signals, taking care to respect 1707 # the precedence described in the specification 1708 if changed and self_is_subnormal: 1709 context._raise_error(Underflow) 1710 if self_is_subnormal: 1711 context._raise_error(Subnormal) 1617 1712 if changed: 1618 1713 context._raise_error(Inexact) 1619 if self_is_subnormal: 1620 context._raise_error(Underflow) 1621 if not ans: 1622 # raise Clamped on underflow to 0 1623 context._raise_error(Clamped) 1624 elif len(ans._int) == context.prec+1: 1625 # we get here only if rescaling rounds the 1626 # cofficient up to exactly 10**context.prec 1627 if ans._exp < Etop: 1628 ans = _dec_from_triple(ans._sign, 1629 ans._int[:-1], ans._exp+1) 1630 else: 1631 # Inexact and Rounded have already been raised 1632 ans = context._raise_error(Overflow, 'above Emax', 1633 self._sign) 1714 context._raise_error(Rounded) 1715 if not ans: 1716 # raise Clamped on underflow to 0 1717 context._raise_error(Clamped) 1634 1718 return ans 1719 1720 if self_is_subnormal: 1721 context._raise_error(Subnormal) 1635 1722 1636 1723 # fold down if _clamp == 1 and self has too few digits … … 1642 1729 # here self was representable to begin with; return unchanged 1643 1730 return Decimal(self) 1644 1645 _pick_rounding_function = {}1646 1731 1647 1732 # for each of the rounding functions below: … … 1710 1795 else: 1711 1796 return -self._round_down(prec) 1797 1798 _pick_rounding_function = dict( 1799 ROUND_DOWN = _round_down, 1800 ROUND_UP = _round_up, 1801 ROUND_HALF_UP = _round_half_up, 1802 ROUND_HALF_DOWN = _round_half_down, 1803 ROUND_HALF_EVEN = _round_half_even, 1804 ROUND_CEILING = _round_ceiling, 1805 ROUND_FLOOR = _round_floor, 1806 ROUND_05UP = _round_05up, 1807 ) 1712 1808 1713 1809 def fma(self, other, third, context=None): … … 1853 1949 so that 10**abs(other._exp) is a feasible calculation.""" 1854 1950 1855 # In the comments below, we write x for the value of self and 1856 # y for the value of other. Write x = xc*10**xe and y =1857 # yc*10**ye.1951 # In the comments below, we write x for the value of self and y for the 1952 # value of other. Write x = xc*10**xe and abs(y) = yc*10**ye, with xc 1953 # and yc positive integers not divisible by 10. 1858 1954 1859 1955 # The main purpose of this method is to identify the *failure* … … 1863 1959 # these tests are passed do we go on to actually compute x**y. 1864 1960 1865 # Here's the main idea. First normalize both x and y. We 1866 # express y as a rational m/n, with m and n relatively prime 1867 # and n>0. Then for x**y to be exactly representable (at 1868 # *any* precision), xc must be the nth power of a positive 1869 # integer and xe must be divisible by n. If m is negative 1870 # then additionally xc must be a power of either 2 or 5, hence 1871 # a power of 2**n or 5**n. 1961 # Here's the main idea. Express y as a rational number m/n, with m and 1962 # n relatively prime and n>0. Then for x**y to be exactly 1963 # representable (at *any* precision), xc must be the nth power of a 1964 # positive integer and xe must be divisible by n. If y is negative 1965 # then additionally xc must be a power of either 2 or 5, hence a power 1966 # of 2**n or 5**n. 1872 1967 # 1873 1968 # There's a limit to how small |y| can be: if y=m/n as above … … 1913 2008 # required to be an integer 1914 2009 if xc == 1: 1915 if ye >= 0: 1916 exponent = xe*yc*10**ye 1917 else: 1918 exponent, remainder = divmod(xe*yc, 10**-ye) 1919 if remainder: 1920 return None 2010 xe *= yc 2011 # result is now 10**(xe * 10**ye); xe * 10**ye must be integral 2012 while xe % 10 == 0: 2013 xe //= 10 2014 ye += 1 2015 if ye < 0: 2016 return None 2017 exponent = xe * 10**ye 1921 2018 if y.sign == 1: 1922 2019 exponent = -exponent … … 1939 2036 # now xc is a power of 2; e is its exponent 1940 2037 e = _nbits(xc)-1 1941 # find e*y and xe*y; both must be integers 1942 if ye >= 0: 1943 y_as_int = yc*10**ye 1944 e = e*y_as_int 1945 xe = xe*y_as_int 1946 else: 1947 ten_pow = 10**-ye 1948 e, remainder = divmod(e*yc, ten_pow) 1949 if remainder: 1950 return None 1951 xe, remainder = divmod(xe*yc, ten_pow) 1952 if remainder: 1953 return None 1954 1955 if e*65 >= p*93: # 93/65 > log(10)/log(5) 2038 2039 # We now have: 2040 # 2041 # x = 2**e * 10**xe, e > 0, and y < 0. 2042 # 2043 # The exact result is: 2044 # 2045 # x**y = 5**(-e*y) * 10**(e*y + xe*y) 2046 # 2047 # provided that both e*y and xe*y are integers. Note that if 2048 # 5**(-e*y) >= 10**p, then the result can't be expressed 2049 # exactly with p digits of precision. 2050 # 2051 # Using the above, we can guard against large values of ye. 2052 # 93/65 is an upper bound for log(10)/log(5), so if 2053 # 2054 # ye >= len(str(93*p//65)) 2055 # 2056 # then 2057 # 2058 # -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5), 2059 # 2060 # so 5**(-e*y) >= 10**p, and the coefficient of the result 2061 # can't be expressed in p digits. 2062 2063 # emax >= largest e such that 5**e < 10**p. 2064 emax = p*93//65 2065 if ye >= len(str(emax)): 2066 return None 2067 2068 # Find -e*y and -xe*y; both must be integers 2069 e = _decimal_lshift_exact(e * yc, ye) 2070 xe = _decimal_lshift_exact(xe * yc, ye) 2071 if e is None or xe is None: 2072 return None 2073 2074 if e > emax: 1956 2075 return None 1957 2076 xc = 5**e … … 1967 2086 xc //= 5 1968 2087 e -= 1 1969 if ye >= 0: 1970 y_as_integer = yc*10**ye 1971 e = e*y_as_integer 1972 xe = xe*y_as_integer 1973 else: 1974 ten_pow = 10**-ye 1975 e, remainder = divmod(e*yc, ten_pow) 1976 if remainder: 1977 return None 1978 xe, remainder = divmod(xe*yc, ten_pow) 1979 if remainder: 1980 return None 1981 if e*3 >= p*10: # 10/3 > log(10)/log(2) 2088 2089 # Guard against large values of ye, using the same logic as in 2090 # the 'xc is a power of 2' branch. 10/3 is an upper bound for 2091 # log(10)/log(2). 2092 emax = p*10//3 2093 if ye >= len(str(emax)): 2094 return None 2095 2096 e = _decimal_lshift_exact(e * yc, ye) 2097 xe = _decimal_lshift_exact(xe * yc, ye) 2098 if e is None or xe is None: 2099 return None 2100 2101 if e > emax: 1982 2102 return None 1983 2103 xc = 2**e … … 2168 2288 # to _fix at the end of this function. 2169 2289 ans = None 2290 exact = False 2170 2291 2171 2292 # crude test to catch cases of extreme overflow/underflow. If … … 2190 2311 if ans is None: 2191 2312 ans = self._power_exact(other, context.prec + 1) 2192 if ans is not None and result_sign == 1: 2193 ans = _dec_from_triple(1, ans._int, ans._exp) 2313 if ans is not None: 2314 if result_sign == 1: 2315 ans = _dec_from_triple(1, ans._int, ans._exp) 2316 exact = True 2194 2317 2195 2318 # usual case: inexact result, x**y computed directly as exp(y*log(x)) … … 2214 2337 ans = _dec_from_triple(result_sign, str(coeff), exp) 2215 2338 2216 # the specification says that for non-integer other we need to 2217 # raise Inexact, even when the result is actually exact. In 2218 # the same way, we need to raise Underflow here if the result 2219 # is subnormal. (The call to _fix will take care of raising 2220 # Rounded and Subnormal, as usual.) 2221 if not other._isinteger(): 2222 context._raise_error(Inexact) 2223 # pad with zeros up to length context.prec+1 if necessary 2339 # unlike exp, ln and log10, the power function respects the 2340 # rounding mode; no need to switch to ROUND_HALF_EVEN here 2341 2342 # There's a difficulty here when 'other' is not an integer and 2343 # the result is exact. In this case, the specification 2344 # requires that the Inexact flag be raised (in spite of 2345 # exactness), but since the result is exact _fix won't do this 2346 # for us. (Correspondingly, the Underflow signal should also 2347 # be raised for subnormal results.) We can't directly raise 2348 # these signals either before or after calling _fix, since 2349 # that would violate the precedence for signals. So we wrap 2350 # the ._fix call in a temporary context, and reraise 2351 # afterwards. 2352 if exact and not other._isinteger(): 2353 # pad with zeros up to length context.prec+1 if necessary; this 2354 # ensures that the Rounded signal will be raised. 2224 2355 if len(ans._int) <= context.prec: 2225 expdiff = context.prec +1 - len(ans._int)2356 expdiff = context.prec + 1 - len(ans._int) 2226 2357 ans = _dec_from_triple(ans._sign, ans._int+'0'*expdiff, 2227 2358 ans._exp-expdiff) 2228 if ans.adjusted() < context.Emin: 2229 context._raise_error(Underflow) 2230 2231 # unlike exp, ln and log10, the power function respects the 2232 # rounding mode; no need to use ROUND_HALF_EVEN here 2233 ans = ans._fix(context) 2359 2360 # create a copy of the current context, with cleared flags/traps 2361 newcontext = context.copy() 2362 newcontext.clear_flags() 2363 for exception in _signals: 2364 newcontext.traps[exception] = 0 2365 2366 # round in the new context 2367 ans = ans._fix(newcontext) 2368 2369 # raise Inexact, and if necessary, Underflow 2370 newcontext._raise_error(Inexact) 2371 if newcontext.flags[Subnormal]: 2372 newcontext._raise_error(Underflow) 2373 2374 # propagate signals to the original context; _fix could 2375 # have raised any of Overflow, Underflow, Subnormal, 2376 # Inexact, Rounded, Clamped. Overflow needs the correct 2377 # arguments. Note that the order of the exceptions is 2378 # important here. 2379 if newcontext.flags[Overflow]: 2380 context._raise_error(Overflow, 'above Emax', ans._sign) 2381 for exception in Underflow, Subnormal, Inexact, Rounded, Clamped: 2382 if newcontext.flags[exception]: 2383 context._raise_error(exception) 2384 2385 else: 2386 ans = ans._fix(context) 2387 2234 2388 return ans 2235 2389 … … 2325 2479 2326 2480 # raise appropriate flags 2481 if ans and ans.adjusted() < context.Emin: 2482 context._raise_error(Subnormal) 2327 2483 if ans._exp > self._exp: 2328 context._raise_error(Rounded)2329 2484 if ans != self: 2330 2485 context._raise_error(Inexact) 2331 if ans and ans.adjusted() < context.Emin:2332 context._raise_error(Subnormal) 2333 2334 # call to fix takes care of any necessary folddown2486 context._raise_error(Rounded) 2487 2488 # call to fix takes care of any necessary folddown, and 2489 # signals Clamped if necessary 2335 2490 ans = ans._fix(context) 2336 2491 return ans … … 2378 2533 self = _dec_from_triple(self._sign, '1', exp-1) 2379 2534 digits = 0 2380 this_function = getattr(self, self._pick_rounding_function[rounding])2381 changed = this_function( digits)2535 this_function = self._pick_rounding_function[rounding] 2536 changed = this_function(self, digits) 2382 2537 coeff = self._int[:digits] or '0' 2383 2538 if changed == 1: … … 2431 2586 if rounding is None: 2432 2587 rounding = context.rounding 2433 context._raise_error(Rounded)2434 2588 ans = self._rescale(0, rounding) 2435 2589 if ans != self: 2436 2590 context._raise_error(Inexact) 2591 context._raise_error(Rounded) 2437 2592 return ans 2438 2593 … … 2771 2926 def copy_sign(self, other): 2772 2927 """Returns self with the sign of other.""" 2928 other = _convert_other(other, raiseit=True) 2773 2929 return _dec_from_triple(other._sign, self._int, 2774 2930 self._exp, self._is_special) … … 3314 3470 'Infinite result from next_toward', 3315 3471 ans._sign) 3472 context._raise_error(Inexact) 3316 3473 context._raise_error(Rounded) 3317 context._raise_error(Inexact)3318 3474 elif ans.adjusted() < context.Emin: 3319 3475 context._raise_error(Underflow) 3320 3476 context._raise_error(Subnormal) 3477 context._raise_error(Inexact) 3321 3478 context._raise_error(Rounded) 3322 context._raise_error(Inexact)3323 3479 # if precision == 1 then we don't raise Clamped for a 3324 3480 # result 0E-Etiny. … … 3475 3631 3476 3632 def __copy__(self): 3477 if type(self) ==Decimal:3633 if type(self) is Decimal: 3478 3634 return self # I'm immutable; therefore I am my own clone 3479 3635 return self.__class__(str(self)) 3480 3636 3481 3637 def __deepcopy__(self, memo): 3482 if type(self) ==Decimal:3638 if type(self) is Decimal: 3483 3639 return self # My components are also immutable 3484 3640 return self.__class__(str(self)) 3485 3641 3486 # PEP 3101 support. See also _parse_format_specifier and _format_align 3487 def __format__(self, specifier, context=None): 3642 # PEP 3101 support. the _localeconv keyword argument should be 3643 # considered private: it's provided for ease of testing only. 3644 def __format__(self, specifier, context=None, _localeconv=None): 3488 3645 """Format a Decimal instance according to the given specifier. 3489 3646 3490 3647 The specifier should be a standard format specifier, with the 3491 3648 form described in PEP 3101. Formatting types 'e', 'E', 'f', 3492 'F', 'g', 'G', and '%' are supported. If the formatting type 3493 is omitted it defaults to 'g' or 'G', depending on the value 3494 of context.capitals. 3495 3496 At this time the 'n' format specifier type (which is supposed 3497 to use the current locale) is not supported. 3649 'F', 'g', 'G', 'n' and '%' are supported. If the formatting 3650 type is omitted it defaults to 'g' or 'G', depending on the 3651 value of context.capitals. 3498 3652 """ 3499 3653 … … 3506 3660 context = getcontext() 3507 3661 3508 spec = _parse_format_specifier(specifier )3509 3510 # special values don't care about the type or precision ...3662 spec = _parse_format_specifier(specifier, _localeconv=_localeconv) 3663 3664 # special values don't care about the type or precision 3511 3665 if self._is_special: 3512 return _format_align(str(self), spec) 3666 sign = _format_sign(self._sign, spec) 3667 body = str(self.copy_abs()) 3668 return _format_align(sign, body, spec) 3513 3669 3514 3670 # a type of None defaults to 'g' or 'G', depending on context 3515 # if type is '%', adjust exponent of self accordingly3516 3671 if spec['type'] is None: 3517 3672 spec['type'] = ['g', 'G'][context.capitals] 3518 elif spec['type'] == '%': 3673 3674 # if type is '%', adjust exponent of self accordingly 3675 if spec['type'] == '%': 3519 3676 self = _dec_from_triple(self._sign, self._int, self._exp+2) 3520 3677 … … 3525 3682 if spec['type'] in 'eE': 3526 3683 self = self._round(precision+1, rounding) 3527 elif spec['type'] in 'gG':3528 if len(self._int) > precision:3529 self = self._round(precision, rounding)3530 3684 elif spec['type'] in 'fF%': 3531 3685 self = self._rescale(-precision, rounding) 3686 elif spec['type'] in 'gG' and len(self._int) > precision: 3687 self = self._round(precision, rounding) 3532 3688 # special case: zeros with a positive exponent can't be 3533 3689 # represented in fixed point; rescale them to 0e0. 3534 elif not self and self._exp > 0 and spec['type'] in 'fF%':3690 if not self and self._exp > 0 and spec['type'] in 'fF%': 3535 3691 self = self._rescale(0, rounding) 3536 3692 3537 3693 # figure out placement of the decimal point 3538 3694 leftdigits = self._exp + len(self._int) 3539 if spec['type'] in 'fF%': 3540 dotplace = leftdigits 3541 elif spec['type'] in 'eE': 3695 if spec['type'] in 'eE': 3542 3696 if not self and precision is not None: 3543 3697 dotplace = 1 - precision 3544 3698 else: 3545 3699 dotplace = 1 3700 elif spec['type'] in 'fF%': 3701 dotplace = leftdigits 3546 3702 elif spec['type'] in 'gG': 3547 3703 if self._exp <= 0 and leftdigits > -6: … … 3550 3706 dotplace = 1 3551 3707 3552 # fi gure out main part of numeric string...3553 if dotplace < =0:3554 num = '0.' + '0'*(-dotplace) + self._int3555 elif dotplace >= len(self._int):3556 # make sure we're not padding a '0' with extra zeros on the right3557 assert dotplace==len(self._int) or self._int != '0'3558 num = self._int + '0'*(dotplace-len(self._int))3708 # find digits before and after decimal point, and get exponent 3709 if dotplace < 0: 3710 intpart = '0' 3711 fracpart = '0'*(-dotplace) + self._int 3712 elif dotplace > len(self._int): 3713 intpart = self._int + '0'*(dotplace-len(self._int)) 3714 fracpart = '' 3559 3715 else: 3560 num = self._int[:dotplace] + '.' + self._int[dotplace:] 3561 3562 # ...then the trailing exponent, or trailing '%' 3563 if leftdigits != dotplace or spec['type'] in 'eE': 3564 echar = {'E': 'E', 'e': 'e', 'G': 'E', 'g': 'e'}[spec['type']] 3565 num = num + "{0}{1:+}".format(echar, leftdigits-dotplace) 3566 elif spec['type'] == '%': 3567 num = num + '%' 3568 3569 # add sign 3570 if self._sign == 1: 3571 num = '-' + num 3572 return _format_align(num, spec) 3573 3716 intpart = self._int[:dotplace] or '0' 3717 fracpart = self._int[dotplace:] 3718 exp = leftdigits-dotplace 3719 3720 # done with the decimal-specific stuff; hand over the rest 3721 # of the formatting to the _format_number function 3722 return _format_number(self._sign, intpart, fracpart, exp, spec) 3574 3723 3575 3724 def _dec_from_triple(sign, coefficient, exponent, special=False): … … 3596 3745 3597 3746 ##### Context class ####################################################### 3598 3599 3600 # get rounding method function:3601 rounding_functions = [name for name in Decimal.__dict__.keys()3602 if name.startswith('_round_')]3603 for name in rounding_functions:3604 # name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.3605 globalname = name[1:].upper()3606 val = globals()[globalname]3607 Decimal._pick_rounding_function[val] = name3608 3609 del name, val, globalname, rounding_functions3610 3747 3611 3748 class _ContextManager(object): … … 3648 3785 capitals=None, _clamp=0, 3649 3786 _ignored_flags=None): 3787 # Set defaults; for everything except flags and _ignored_flags, 3788 # inherit from DefaultContext. 3789 try: 3790 dc = DefaultContext 3791 except NameError: 3792 pass 3793 3794 self.prec = prec if prec is not None else dc.prec 3795 self.rounding = rounding if rounding is not None else dc.rounding 3796 self.Emin = Emin if Emin is not None else dc.Emin 3797 self.Emax = Emax if Emax is not None else dc.Emax 3798 self.capitals = capitals if capitals is not None else dc.capitals 3799 self._clamp = _clamp if _clamp is not None else dc._clamp 3800 3801 if _ignored_flags is None: 3802 self._ignored_flags = [] 3803 else: 3804 self._ignored_flags = _ignored_flags 3805 3806 if traps is None: 3807 self.traps = dc.traps.copy() 3808 elif not isinstance(traps, dict): 3809 self.traps = dict((s, int(s in traps)) for s in _signals) 3810 else: 3811 self.traps = traps 3812 3650 3813 if flags is None: 3651 flags = [] 3652 if _ignored_flags is None: 3653 _ignored_flags = [] 3654 if not isinstance(flags, dict): 3655 flags = dict([(s, int(s in flags)) for s in _signals]) 3656 del s 3657 if traps is not None and not isinstance(traps, dict): 3658 traps = dict([(s, int(s in traps)) for s in _signals]) 3659 del s 3660 for name, val in locals().items(): 3661 if val is None: 3662 setattr(self, name, _copy.copy(getattr(DefaultContext, name))) 3663 else: 3664 setattr(self, name, val) 3665 del self.self 3814 self.flags = dict.fromkeys(_signals, 0) 3815 elif not isinstance(flags, dict): 3816 self.flags = dict((s, int(s in flags)) for s in _signals) 3817 else: 3818 self.flags = flags 3666 3819 3667 3820 def __repr__(self): … … 3702 3855 If the flag is in _ignored_flags, returns the default response. 3703 3856 Otherwise, it sets the flag, then, if the corresponding 3704 trap_enabler is set, it re aises the exception. Otherwise, it returns3857 trap_enabler is set, it reraises the exception. Otherwise, it returns 3705 3858 the default value after setting the flag. 3706 3859 """ … … 3783 3936 "diagnostic info too long in NaN") 3784 3937 return d._fix(self) 3938 3939 def create_decimal_from_float(self, f): 3940 """Creates a new Decimal instance from a float but rounding using self 3941 as the context. 3942 3943 >>> context = Context(prec=5, rounding=ROUND_DOWN) 3944 >>> context.create_decimal_from_float(3.1415926535897932) 3945 Decimal('3.1415') 3946 >>> context = Context(prec=5, traps=[Inexact]) 3947 >>> context.create_decimal_from_float(3.1415926535897932) 3948 Traceback (most recent call last): 3949 ... 3950 Inexact: None 3951 3952 """ 3953 d = Decimal.from_float(f) # An exact conversion 3954 return d._fix(self) # Apply the context rounding 3785 3955 3786 3956 # Methods … … 3800 3970 >>> ExtendedContext.abs(Decimal('-101.5')) 3801 3971 Decimal('101.5') 3802 """ 3972 >>> ExtendedContext.abs(-1) 3973 Decimal('1') 3974 """ 3975 a = _convert_other(a, raiseit=True) 3803 3976 return a.__abs__(context=self) 3804 3977 … … 3810 3983 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4')) 3811 3984 Decimal('1.02E+4') 3812 """ 3813 return a.__add__(b, context=self) 3985 >>> ExtendedContext.add(1, Decimal(2)) 3986 Decimal('3') 3987 >>> ExtendedContext.add(Decimal(8), 5) 3988 Decimal('13') 3989 >>> ExtendedContext.add(5, 5) 3990 Decimal('10') 3991 """ 3992 a = _convert_other(a, raiseit=True) 3993 r = a.__add__(b, context=self) 3994 if r is NotImplemented: 3995 raise TypeError("Unable to convert %s to Decimal" % b) 3996 else: 3997 return r 3814 3998 3815 3999 def _apply(self, a): … … 3853 4037 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1')) 3854 4038 Decimal('-1') 3855 """ 4039 >>> ExtendedContext.compare(1, 2) 4040 Decimal('-1') 4041 >>> ExtendedContext.compare(Decimal(1), 2) 4042 Decimal('-1') 4043 >>> ExtendedContext.compare(1, Decimal(2)) 4044 Decimal('-1') 4045 """ 4046 a = _convert_other(a, raiseit=True) 3856 4047 return a.compare(b, context=self) 3857 4048 … … 3881 4072 >>> print c.flags[InvalidOperation] 3882 4073 1 3883 """ 4074 >>> c.compare_signal(-1, 2) 4075 Decimal('-1') 4076 >>> c.compare_signal(Decimal(-1), 2) 4077 Decimal('-1') 4078 >>> c.compare_signal(-1, Decimal(2)) 4079 Decimal('-1') 4080 """ 4081 a = _convert_other(a, raiseit=True) 3884 4082 return a.compare_signal(b, context=self) 3885 4083 … … 3903 4101 >>> ExtendedContext.compare_total(Decimal('12.3'), Decimal('NaN')) 3904 4102 Decimal('-1') 3905 """ 4103 >>> ExtendedContext.compare_total(1, 2) 4104 Decimal('-1') 4105 >>> ExtendedContext.compare_total(Decimal(1), 2) 4106 Decimal('-1') 4107 >>> ExtendedContext.compare_total(1, Decimal(2)) 4108 Decimal('-1') 4109 """ 4110 a = _convert_other(a, raiseit=True) 3906 4111 return a.compare_total(b) 3907 4112 … … 3911 4116 Like compare_total, but with operand's sign ignored and assumed to be 0. 3912 4117 """ 4118 a = _convert_other(a, raiseit=True) 3913 4119 return a.compare_total_mag(b) 3914 4120 … … 3920 4126 >>> ExtendedContext.copy_abs(Decimal('-100')) 3921 4127 Decimal('100') 3922 """ 4128 >>> ExtendedContext.copy_abs(-1) 4129 Decimal('1') 4130 """ 4131 a = _convert_other(a, raiseit=True) 3923 4132 return a.copy_abs() 3924 4133 3925 4134 def copy_decimal(self, a): 3926 """Returns a copy of the decimal obje t.4135 """Returns a copy of the decimal object. 3927 4136 3928 4137 >>> ExtendedContext.copy_decimal(Decimal('2.1')) … … 3930 4139 >>> ExtendedContext.copy_decimal(Decimal('-1.00')) 3931 4140 Decimal('-1.00') 3932 """ 4141 >>> ExtendedContext.copy_decimal(1) 4142 Decimal('1') 4143 """ 4144 a = _convert_other(a, raiseit=True) 3933 4145 return Decimal(a) 3934 4146 … … 3940 4152 >>> ExtendedContext.copy_negate(Decimal('-101.5')) 3941 4153 Decimal('101.5') 3942 """ 4154 >>> ExtendedContext.copy_negate(1) 4155 Decimal('-1') 4156 """ 4157 a = _convert_other(a, raiseit=True) 3943 4158 return a.copy_negate() 3944 4159 … … 3957 4172 >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('-7.33')) 3958 4173 Decimal('-1.50') 3959 """ 4174 >>> ExtendedContext.copy_sign(1, -2) 4175 Decimal('-1') 4176 >>> ExtendedContext.copy_sign(Decimal(1), -2) 4177 Decimal('-1') 4178 >>> ExtendedContext.copy_sign(1, Decimal(-2)) 4179 Decimal('-1') 4180 """ 4181 a = _convert_other(a, raiseit=True) 3960 4182 return a.copy_sign(b) 3961 4183 … … 3983 4205 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2')) 3984 4206 Decimal('1.20E+6') 3985 """ 3986 return a.__div__(b, context=self) 4207 >>> ExtendedContext.divide(5, 5) 4208 Decimal('1') 4209 >>> ExtendedContext.divide(Decimal(5), 5) 4210 Decimal('1') 4211 >>> ExtendedContext.divide(5, Decimal(5)) 4212 Decimal('1') 4213 """ 4214 a = _convert_other(a, raiseit=True) 4215 r = a.__div__(b, context=self) 4216 if r is NotImplemented: 4217 raise TypeError("Unable to convert %s to Decimal" % b) 4218 else: 4219 return r 3987 4220 3988 4221 def divide_int(self, a, b): … … 3995 4228 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3')) 3996 4229 Decimal('3') 3997 """ 3998 return a.__floordiv__(b, context=self) 4230 >>> ExtendedContext.divide_int(10, 3) 4231 Decimal('3') 4232 >>> ExtendedContext.divide_int(Decimal(10), 3) 4233 Decimal('3') 4234 >>> ExtendedContext.divide_int(10, Decimal(3)) 4235 Decimal('3') 4236 """ 4237 a = _convert_other(a, raiseit=True) 4238 r = a.__floordiv__(b, context=self) 4239 if r is NotImplemented: 4240 raise TypeError("Unable to convert %s to Decimal" % b) 4241 else: 4242 return r 3999 4243 4000 4244 def divmod(self, a, b): 4001 """Return (a // b, a % b) 4245 """Return (a // b, a % b). 4002 4246 4003 4247 >>> ExtendedContext.divmod(Decimal(8), Decimal(3)) … … 4005 4249 >>> ExtendedContext.divmod(Decimal(8), Decimal(4)) 4006 4250 (Decimal('2'), Decimal('0')) 4007 """ 4008 return a.__divmod__(b, context=self) 4251 >>> ExtendedContext.divmod(8, 4) 4252 (Decimal('2'), Decimal('0')) 4253 >>> ExtendedContext.divmod(Decimal(8), 4) 4254 (Decimal('2'), Decimal('0')) 4255 >>> ExtendedContext.divmod(8, Decimal(4)) 4256 (Decimal('2'), Decimal('0')) 4257 """ 4258 a = _convert_other(a, raiseit=True) 4259 r = a.__divmod__(b, context=self) 4260 if r is NotImplemented: 4261 raise TypeError("Unable to convert %s to Decimal" % b) 4262 else: 4263 return r 4009 4264 4010 4265 def exp(self, a): … … 4026 4281 >>> c.exp(Decimal('+Infinity')) 4027 4282 Decimal('Infinity') 4028 """ 4283 >>> c.exp(10) 4284 Decimal('22026.4658') 4285 """ 4286 a =_convert_other(a, raiseit=True) 4029 4287 return a.exp(context=self) 4030 4288 … … 4042 4300 >>> ExtendedContext.fma(Decimal('888565290'), Decimal('1557.96930'), Decimal('-86087.7578')) 4043 4301 Decimal('1.38435736E+12') 4044 """ 4302 >>> ExtendedContext.fma(1, 3, 4) 4303 Decimal('7') 4304 >>> ExtendedContext.fma(1, Decimal(3), 4) 4305 Decimal('7') 4306 >>> ExtendedContext.fma(1, 3, Decimal(4)) 4307 Decimal('7') 4308 """ 4309 a = _convert_other(a, raiseit=True) 4045 4310 return a.fma(b, c, context=self) 4046 4311 … … 4072 4337 >>> ExtendedContext.is_finite(Decimal('NaN')) 4073 4338 False 4074 """ 4339 >>> ExtendedContext.is_finite(1) 4340 True 4341 """ 4342 a = _convert_other(a, raiseit=True) 4075 4343 return a.is_finite() 4076 4344 … … 4084 4352 >>> ExtendedContext.is_infinite(Decimal('NaN')) 4085 4353 False 4086 """ 4354 >>> ExtendedContext.is_infinite(1) 4355 False 4356 """ 4357 a = _convert_other(a, raiseit=True) 4087 4358 return a.is_infinite() 4088 4359 … … 4097 4368 >>> ExtendedContext.is_nan(Decimal('-sNaN')) 4098 4369 True 4099 """ 4370 >>> ExtendedContext.is_nan(1) 4371 False 4372 """ 4373 a = _convert_other(a, raiseit=True) 4100 4374 return a.is_nan() 4101 4375 … … 4117 4391 >>> c.is_normal(Decimal('NaN')) 4118 4392 False 4119 """ 4393 >>> c.is_normal(1) 4394 True 4395 """ 4396 a = _convert_other(a, raiseit=True) 4120 4397 return a.is_normal(context=self) 4121 4398 … … 4129 4406 >>> ExtendedContext.is_qnan(Decimal('sNaN')) 4130 4407 False 4131 """ 4408 >>> ExtendedContext.is_qnan(1) 4409 False 4410 """ 4411 a = _convert_other(a, raiseit=True) 4132 4412 return a.is_qnan() 4133 4413 … … 4141 4421 >>> ExtendedContext.is_signed(Decimal('-0')) 4142 4422 True 4143 """ 4423 >>> ExtendedContext.is_signed(8) 4424 False 4425 >>> ExtendedContext.is_signed(-8) 4426 True 4427 """ 4428 a = _convert_other(a, raiseit=True) 4144 4429 return a.is_signed() 4145 4430 … … 4154 4439 >>> ExtendedContext.is_snan(Decimal('sNaN')) 4155 4440 True 4156 """ 4441 >>> ExtendedContext.is_snan(1) 4442 False 4443 """ 4444 a = _convert_other(a, raiseit=True) 4157 4445 return a.is_snan() 4158 4446 … … 4173 4461 >>> c.is_subnormal(Decimal('NaN')) 4174 4462 False 4175 """ 4463 >>> c.is_subnormal(1) 4464 False 4465 """ 4466 a = _convert_other(a, raiseit=True) 4176 4467 return a.is_subnormal(context=self) 4177 4468 … … 4185 4476 >>> ExtendedContext.is_zero(Decimal('-0E+2')) 4186 4477 True 4187 """ 4478 >>> ExtendedContext.is_zero(1) 4479 False 4480 >>> ExtendedContext.is_zero(0) 4481 True 4482 """ 4483 a = _convert_other(a, raiseit=True) 4188 4484 return a.is_zero() 4189 4485 … … 4204 4500 >>> c.ln(Decimal('+Infinity')) 4205 4501 Decimal('Infinity') 4206 """ 4502 >>> c.ln(1) 4503 Decimal('0') 4504 """ 4505 a = _convert_other(a, raiseit=True) 4207 4506 return a.ln(context=self) 4208 4507 … … 4227 4526 >>> c.log10(Decimal('+Infinity')) 4228 4527 Decimal('Infinity') 4229 """ 4528 >>> c.log10(0) 4529 Decimal('-Infinity') 4530 >>> c.log10(1) 4531 Decimal('0') 4532 """ 4533 a = _convert_other(a, raiseit=True) 4230 4534 return a.log10(context=self) 4231 4535 … … 4246 4550 >>> ExtendedContext.logb(Decimal('0')) 4247 4551 Decimal('-Infinity') 4248 """ 4552 >>> ExtendedContext.logb(1) 4553 Decimal('0') 4554 >>> ExtendedContext.logb(10) 4555 Decimal('1') 4556 >>> ExtendedContext.logb(100) 4557 Decimal('2') 4558 """ 4559 a = _convert_other(a, raiseit=True) 4249 4560 return a.logb(context=self) 4250 4561 … … 4266 4577 >>> ExtendedContext.logical_and(Decimal('1111'), Decimal('10')) 4267 4578 Decimal('10') 4268 """ 4579 >>> ExtendedContext.logical_and(110, 1101) 4580 Decimal('100') 4581 >>> ExtendedContext.logical_and(Decimal(110), 1101) 4582 Decimal('100') 4583 >>> ExtendedContext.logical_and(110, Decimal(1101)) 4584 Decimal('100') 4585 """ 4586 a = _convert_other(a, raiseit=True) 4269 4587 return a.logical_and(b, context=self) 4270 4588 … … 4282 4600 >>> ExtendedContext.logical_invert(Decimal('101010101')) 4283 4601 Decimal('10101010') 4284 """ 4602 >>> ExtendedContext.logical_invert(1101) 4603 Decimal('111110010') 4604 """ 4605 a = _convert_other(a, raiseit=True) 4285 4606 return a.logical_invert(context=self) 4286 4607 … … 4302 4623 >>> ExtendedContext.logical_or(Decimal('1110'), Decimal('10')) 4303 4624 Decimal('1110') 4304 """ 4625 >>> ExtendedContext.logical_or(110, 1101) 4626 Decimal('1111') 4627 >>> ExtendedContext.logical_or(Decimal(110), 1101) 4628 Decimal('1111') 4629 >>> ExtendedContext.logical_or(110, Decimal(1101)) 4630 Decimal('1111') 4631 """ 4632 a = _convert_other(a, raiseit=True) 4305 4633 return a.logical_or(b, context=self) 4306 4634 … … 4322 4650 >>> ExtendedContext.logical_xor(Decimal('1111'), Decimal('10')) 4323 4651 Decimal('1101') 4324 """ 4652 >>> ExtendedContext.logical_xor(110, 1101) 4653 Decimal('1011') 4654 >>> ExtendedContext.logical_xor(Decimal(110), 1101) 4655 Decimal('1011') 4656 >>> ExtendedContext.logical_xor(110, Decimal(1101)) 4657 Decimal('1011') 4658 """ 4659 a = _convert_other(a, raiseit=True) 4325 4660 return a.logical_xor(b, context=self) 4326 4661 4327 def max(self, a, b):4662 def max(self, a, b): 4328 4663 """max compares two values numerically and returns the maximum. 4329 4664 … … 4342 4677 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN')) 4343 4678 Decimal('7') 4344 """ 4679 >>> ExtendedContext.max(1, 2) 4680 Decimal('2') 4681 >>> ExtendedContext.max(Decimal(1), 2) 4682 Decimal('2') 4683 >>> ExtendedContext.max(1, Decimal(2)) 4684 Decimal('2') 4685 """ 4686 a = _convert_other(a, raiseit=True) 4345 4687 return a.max(b, context=self) 4346 4688 4347 4689 def max_mag(self, a, b): 4348 """Compares the values numerically with their sign ignored.""" 4690 """Compares the values numerically with their sign ignored. 4691 4692 >>> ExtendedContext.max_mag(Decimal('7'), Decimal('NaN')) 4693 Decimal('7') 4694 >>> ExtendedContext.max_mag(Decimal('7'), Decimal('-10')) 4695 Decimal('-10') 4696 >>> ExtendedContext.max_mag(1, -2) 4697 Decimal('-2') 4698 >>> ExtendedContext.max_mag(Decimal(1), -2) 4699 Decimal('-2') 4700 >>> ExtendedContext.max_mag(1, Decimal(-2)) 4701 Decimal('-2') 4702 """ 4703 a = _convert_other(a, raiseit=True) 4349 4704 return a.max_mag(b, context=self) 4350 4705 4351 def min(self, a, b):4706 def min(self, a, b): 4352 4707 """min compares two values numerically and returns the minimum. 4353 4708 … … 4366 4721 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN')) 4367 4722 Decimal('7') 4368 """ 4723 >>> ExtendedContext.min(1, 2) 4724 Decimal('1') 4725 >>> ExtendedContext.min(Decimal(1), 2) 4726 Decimal('1') 4727 >>> ExtendedContext.min(1, Decimal(29)) 4728 Decimal('1') 4729 """ 4730 a = _convert_other(a, raiseit=True) 4369 4731 return a.min(b, context=self) 4370 4732 4371 4733 def min_mag(self, a, b): 4372 """Compares the values numerically with their sign ignored.""" 4734 """Compares the values numerically with their sign ignored. 4735 4736 >>> ExtendedContext.min_mag(Decimal('3'), Decimal('-2')) 4737 Decimal('-2') 4738 >>> ExtendedContext.min_mag(Decimal('-3'), Decimal('NaN')) 4739 Decimal('-3') 4740 >>> ExtendedContext.min_mag(1, -2) 4741 Decimal('1') 4742 >>> ExtendedContext.min_mag(Decimal(1), -2) 4743 Decimal('1') 4744 >>> ExtendedContext.min_mag(1, Decimal(-2)) 4745 Decimal('1') 4746 """ 4747 a = _convert_other(a, raiseit=True) 4373 4748 return a.min_mag(b, context=self) 4374 4749 … … 4384 4759 >>> ExtendedContext.minus(Decimal('-1.3')) 4385 4760 Decimal('1.3') 4386 """ 4761 >>> ExtendedContext.minus(1) 4762 Decimal('-1') 4763 """ 4764 a = _convert_other(a, raiseit=True) 4387 4765 return a.__neg__(context=self) 4388 4766 … … 4391 4769 4392 4770 If either operand is a special value then the general rules apply. 4393 Otherwise, the operands are multiplied together ('long multiplication'),4394 resulting in a number which may be as long as the sum of the lengths4395 of the two operands.4771 Otherwise, the operands are multiplied together 4772 ('long multiplication'), resulting in a number which may be as long as 4773 the sum of the lengths of the two operands. 4396 4774 4397 4775 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3')) … … 4405 4783 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321')) 4406 4784 Decimal('4.28135971E+11') 4407 """ 4408 return a.__mul__(b, context=self) 4785 >>> ExtendedContext.multiply(7, 7) 4786 Decimal('49') 4787 >>> ExtendedContext.multiply(Decimal(7), 7) 4788 Decimal('49') 4789 >>> ExtendedContext.multiply(7, Decimal(7)) 4790 Decimal('49') 4791 """ 4792 a = _convert_other(a, raiseit=True) 4793 r = a.__mul__(b, context=self) 4794 if r is NotImplemented: 4795 raise TypeError("Unable to convert %s to Decimal" % b) 4796 else: 4797 return r 4409 4798 4410 4799 def next_minus(self, a): … … 4422 4811 >>> c.next_minus(Decimal('Infinity')) 4423 4812 Decimal('9.99999999E+999') 4424 """ 4813 >>> c.next_minus(1) 4814 Decimal('0.999999999') 4815 """ 4816 a = _convert_other(a, raiseit=True) 4425 4817 return a.next_minus(context=self) 4426 4818 … … 4439 4831 >>> c.next_plus(Decimal('-Infinity')) 4440 4832 Decimal('-9.99999999E+999') 4441 """ 4833 >>> c.next_plus(1) 4834 Decimal('1.00000001') 4835 """ 4836 a = _convert_other(a, raiseit=True) 4442 4837 return a.next_plus(context=self) 4443 4838 … … 4467 4862 >>> c.next_toward(Decimal('0.00'), Decimal('-0.0000')) 4468 4863 Decimal('-0.00') 4469 """ 4864 >>> c.next_toward(0, 1) 4865 Decimal('1E-1007') 4866 >>> c.next_toward(Decimal(0), 1) 4867 Decimal('1E-1007') 4868 >>> c.next_toward(0, Decimal(1)) 4869 Decimal('1E-1007') 4870 """ 4871 a = _convert_other(a, raiseit=True) 4470 4872 return a.next_toward(b, context=self) 4471 4873 … … 4488 4890 >>> ExtendedContext.normalize(Decimal('0.00')) 4489 4891 Decimal('0') 4490 """ 4892 >>> ExtendedContext.normalize(6) 4893 Decimal('6') 4894 """ 4895 a = _convert_other(a, raiseit=True) 4491 4896 return a.normalize(context=self) 4492 4897 … … 4535 4940 >>> c.number_class(Decimal('sNaN')) 4536 4941 'sNaN' 4537 """ 4942 >>> c.number_class(123) 4943 '+Normal' 4944 """ 4945 a = _convert_other(a, raiseit=True) 4538 4946 return a.number_class(context=self) 4539 4947 … … 4549 4957 >>> ExtendedContext.plus(Decimal('-1.3')) 4550 4958 Decimal('-1.3') 4551 """ 4959 >>> ExtendedContext.plus(-1) 4960 Decimal('-1') 4961 """ 4962 a = _convert_other(a, raiseit=True) 4552 4963 return a.__pos__(context=self) 4553 4964 … … 4618 5029 >>> c.power(Decimal('-23'), Decimal('0'), Decimal('65537')) 4619 5030 Decimal('1') 4620 """ 4621 return a.__pow__(b, modulo, context=self) 5031 >>> ExtendedContext.power(7, 7) 5032 Decimal('823543') 5033 >>> ExtendedContext.power(Decimal(7), 7) 5034 Decimal('823543') 5035 >>> ExtendedContext.power(7, Decimal(7), 2) 5036 Decimal('1') 5037 """ 5038 a = _convert_other(a, raiseit=True) 5039 r = a.__pow__(b, modulo, context=self) 5040 if r is NotImplemented: 5041 raise TypeError("Unable to convert %s to Decimal" % b) 5042 else: 5043 return r 4622 5044 4623 5045 def quantize(self, a, b): … … 4669 5091 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2')) 4670 5092 Decimal('2E+2') 4671 """ 5093 >>> ExtendedContext.quantize(1, 2) 5094 Decimal('1') 5095 >>> ExtendedContext.quantize(Decimal(1), 2) 5096 Decimal('1') 5097 >>> ExtendedContext.quantize(1, Decimal(2)) 5098 Decimal('1') 5099 """ 5100 a = _convert_other(a, raiseit=True) 4672 5101 return a.quantize(b, context=self) 4673 5102 … … 4704 5133 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3')) 4705 5134 Decimal('1.0') 4706 """ 4707 return a.__mod__(b, context=self) 5135 >>> ExtendedContext.remainder(22, 6) 5136 Decimal('4') 5137 >>> ExtendedContext.remainder(Decimal(22), 6) 5138 Decimal('4') 5139 >>> ExtendedContext.remainder(22, Decimal(6)) 5140 Decimal('4') 5141 """ 5142 a = _convert_other(a, raiseit=True) 5143 r = a.__mod__(b, context=self) 5144 if r is NotImplemented: 5145 raise TypeError("Unable to convert %s to Decimal" % b) 5146 else: 5147 return r 4708 5148 4709 5149 def remainder_near(self, a, b): … … 4731 5171 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3')) 4732 5172 Decimal('-0.3') 4733 """ 5173 >>> ExtendedContext.remainder_near(3, 11) 5174 Decimal('3') 5175 >>> ExtendedContext.remainder_near(Decimal(3), 11) 5176 Decimal('3') 5177 >>> ExtendedContext.remainder_near(3, Decimal(11)) 5178 Decimal('3') 5179 """ 5180 a = _convert_other(a, raiseit=True) 4734 5181 return a.remainder_near(b, context=self) 4735 5182 … … 4753 5200 >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('+2')) 4754 5201 Decimal('345678912') 4755 """ 5202 >>> ExtendedContext.rotate(1333333, 1) 5203 Decimal('13333330') 5204 >>> ExtendedContext.rotate(Decimal(1333333), 1) 5205 Decimal('13333330') 5206 >>> ExtendedContext.rotate(1333333, Decimal(1)) 5207 Decimal('13333330') 5208 """ 5209 a = _convert_other(a, raiseit=True) 4756 5210 return a.rotate(b, context=self) 4757 5211 … … 4770 5224 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf')) 4771 5225 True 4772 """ 5226 >>> ExtendedContext.same_quantum(10000, -1) 5227 True 5228 >>> ExtendedContext.same_quantum(Decimal(10000), -1) 5229 True 5230 >>> ExtendedContext.same_quantum(10000, Decimal(-1)) 5231 True 5232 """ 5233 a = _convert_other(a, raiseit=True) 4773 5234 return a.same_quantum(b) 4774 5235 … … 4782 5243 >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('3')) 4783 5244 Decimal('7.50E+3') 4784 """ 4785 return a.scaleb (b, context=self) 5245 >>> ExtendedContext.scaleb(1, 4) 5246 Decimal('1E+4') 5247 >>> ExtendedContext.scaleb(Decimal(1), 4) 5248 Decimal('1E+4') 5249 >>> ExtendedContext.scaleb(1, Decimal(4)) 5250 Decimal('1E+4') 5251 """ 5252 a = _convert_other(a, raiseit=True) 5253 return a.scaleb(b, context=self) 4786 5254 4787 5255 def shift(self, a, b): … … 4805 5273 >>> ExtendedContext.shift(Decimal('123456789'), Decimal('+2')) 4806 5274 Decimal('345678900') 4807 """ 5275 >>> ExtendedContext.shift(88888888, 2) 5276 Decimal('888888800') 5277 >>> ExtendedContext.shift(Decimal(88888888), 2) 5278 Decimal('888888800') 5279 >>> ExtendedContext.shift(88888888, Decimal(2)) 5280 Decimal('888888800') 5281 """ 5282 a = _convert_other(a, raiseit=True) 4808 5283 return a.shift(b, context=self) 4809 5284 … … 4832 5307 >>> ExtendedContext.sqrt(Decimal('10')) 4833 5308 Decimal('3.16227766') 5309 >>> ExtendedContext.sqrt(2) 5310 Decimal('1.41421356') 4834 5311 >>> ExtendedContext.prec 4835 5312 9 4836 5313 """ 5314 a = _convert_other(a, raiseit=True) 4837 5315 return a.sqrt(context=self) 4838 5316 … … 4846 5324 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07')) 4847 5325 Decimal('-0.77') 4848 """ 4849 return a.__sub__(b, context=self) 5326 >>> ExtendedContext.subtract(8, 5) 5327 Decimal('3') 5328 >>> ExtendedContext.subtract(Decimal(8), 5) 5329 Decimal('3') 5330 >>> ExtendedContext.subtract(8, Decimal(5)) 5331 Decimal('3') 5332 """ 5333 a = _convert_other(a, raiseit=True) 5334 r = a.__sub__(b, context=self) 5335 if r is NotImplemented: 5336 raise TypeError("Unable to convert %s to Decimal" % b) 5337 else: 5338 return r 4850 5339 4851 5340 def to_eng_string(self, a): … … 4854 5343 The operation is not affected by the context. 4855 5344 """ 5345 a = _convert_other(a, raiseit=True) 4856 5346 return a.to_eng_string(context=self) 4857 5347 … … 4861 5351 The operation is not affected by the context. 4862 5352 """ 5353 a = _convert_other(a, raiseit=True) 4863 5354 return a.__str__(context=self) 4864 5355 … … 4890 5381 Decimal('-Infinity') 4891 5382 """ 5383 a = _convert_other(a, raiseit=True) 4892 5384 return a.to_integral_exact(context=self) 4893 5385 … … 4918 5410 Decimal('-Infinity') 4919 5411 """ 5412 a = _convert_other(a, raiseit=True) 4920 5413 return a.to_integral_value(context=self) 4921 5414 … … 4998 5491 hex_n = "%x" % n 4999 5492 return 4*len(hex_n) - correction[hex_n[0]] 5493 5494 def _decimal_lshift_exact(n, e): 5495 """ Given integers n and e, return n * 10**e if it's an integer, else None. 5496 5497 The computation is designed to avoid computing large powers of 10 5498 unnecessarily. 5499 5500 >>> _decimal_lshift_exact(3, 4) 5501 30000 5502 >>> _decimal_lshift_exact(300, -999999999) # returns None 5503 5504 """ 5505 if n == 0: 5506 return 0 5507 elif e >= 0: 5508 return n * 10**e 5509 else: 5510 # val_n = largest power of 10 dividing n. 5511 str_n = str(abs(n)) 5512 val_n = len(str_n) - len(str_n.rstrip('0')) 5513 return None if val_n < -e else n // 10**-e 5000 5514 5001 5515 def _sqrt_nearest(n, a): … … 5319 5833 ##### Helper Functions #################################################### 5320 5834 5321 def _convert_other(other, raiseit=False ):5835 def _convert_other(other, raiseit=False, allow_float=False): 5322 5836 """Convert other to Decimal. 5323 5837 5324 5838 Verifies that it's ok to use in an implicit construction. 5839 If allow_float is true, allow conversion from float; this 5840 is used in the comparison methods (__eq__ and friends). 5841 5325 5842 """ 5326 5843 if isinstance(other, Decimal): … … 5328 5845 if isinstance(other, (int, long)): 5329 5846 return Decimal(other) 5847 if allow_float and isinstance(other, float): 5848 return Decimal.from_float(other) 5849 5330 5850 if raiseit: 5331 5851 raise TypeError("Unable to convert %s to Decimal" % other) … … 5402 5922 5403 5923 ##### PEP3101 support functions ############################################## 5404 # The functions parse_format_specifier and format_align have little to do5405 # with the Decimal class, and could potentially be reused for other pure5924 # The functions in this section have little to do with the Decimal 5925 # class, and could potentially be reused or adapted for other pure 5406 5926 # Python numeric classes that want to implement __format__ 5407 5927 # 5408 5928 # A format specifier for Decimal looks like: 5409 5929 # 5410 # [[fill]align][sign][0][minimumwidth][.precision][type] 5411 # 5930 # [[fill]align][sign][0][minimumwidth][,][.precision][type] 5412 5931 5413 5932 _parse_format_specifier_regex = re.compile(r"""\A … … 5419 5938 (?P<zeropad>0)? 5420 5939 (?P<minimumwidth>(?!0)\d+)? 5940 (?P<thousands_sep>,)? 5421 5941 (?:\.(?P<precision>0|(?!0)\d+))? 5422 (?P<type>[eEfFgG %])?5942 (?P<type>[eEfFgGn%])? 5423 5943 \Z 5424 5944 """, re.VERBOSE) … … 5426 5946 del re 5427 5947 5428 def _parse_format_specifier(format_spec): 5948 # The locale module is only needed for the 'n' format specifier. The 5949 # rest of the PEP 3101 code functions quite happily without it, so we 5950 # don't care too much if locale isn't present. 5951 try: 5952 import locale as _locale 5953 except ImportError: 5954 pass 5955 5956 def _parse_format_specifier(format_spec, _localeconv=None): 5429 5957 """Parse and validate a format specifier. 5430 5958 … … 5436 5964 sign: either '+', '-' or ' ' 5437 5965 minimumwidth: nonnegative integer giving minimum width 5966 zeropad: boolean, indicating whether to pad with zeros 5967 thousands_sep: string to use as thousands separator, or '' 5968 grouping: grouping for thousands separators, in format 5969 used by localeconv 5970 decimal_point: string to use for decimal point 5438 5971 precision: nonnegative integer giving precision, or None 5439 5972 type: one of the characters 'eEfFgG%', or None 5440 unicode: either True or False(always True for Python 3.x)5973 unicode: boolean (always True for Python 3.x) 5441 5974 5442 5975 """ … … 5448 5981 format_dict = m.groupdict() 5449 5982 5450 # defaults for fill and alignment 5983 # zeropad; defaults for fill and alignment. If zero padding 5984 # is requested, the fill and align fields should be absent. 5451 5985 fill = format_dict['fill'] 5452 5986 align = format_dict['align'] 5453 if format_dict.pop('zeropad') is not None:5454 # in the face of conflict, refuse the temptation to guess5455 if fill is not None and fill != '0':5987 format_dict['zeropad'] = (format_dict['zeropad'] is not None) 5988 if format_dict['zeropad']: 5989 if fill is not None: 5456 5990 raise ValueError("Fill character conflicts with '0'" 5457 5991 " in format specifier: " + format_spec) 5458 if align is not None and align != '=':5992 if align is not None: 5459 5993 raise ValueError("Alignment conflicts with '0' in " 5460 5994 "format specifier: " + format_spec) 5461 fill = '0'5462 align = '='5463 5995 format_dict['fill'] = fill or ' ' 5464 format_dict['align'] = align or '<' 5465 5996 # PEP 3101 originally specified that the default alignment should 5997 # be left; it was later agreed that right-aligned makes more sense 5998 # for numeric types. See http://bugs.python.org/issue6857. 5999 format_dict['align'] = align or '>' 6000 6001 # default sign handling: '-' for negative, '' for positive 5466 6002 if format_dict['sign'] is None: 5467 6003 format_dict['sign'] = '-' 5468 6004 5469 # turn minimumwidth and precision entries into integers.5470 6005 # minimumwidth defaults to 0; precision remains None if not given 5471 6006 format_dict['minimumwidth'] = int(format_dict['minimumwidth'] or '0') … … 5479 6014 format_dict['precision'] = 1 5480 6015 6016 # determine thousands separator, grouping, and decimal separator, and 6017 # add appropriate entries to format_dict 6018 if format_dict['type'] == 'n': 6019 # apart from separators, 'n' behaves just like 'g' 6020 format_dict['type'] = 'g' 6021 if _localeconv is None: 6022 _localeconv = _locale.localeconv() 6023 if format_dict['thousands_sep'] is not None: 6024 raise ValueError("Explicit thousands separator conflicts with " 6025 "'n' type in format specifier: " + format_spec) 6026 format_dict['thousands_sep'] = _localeconv['thousands_sep'] 6027 format_dict['grouping'] = _localeconv['grouping'] 6028 format_dict['decimal_point'] = _localeconv['decimal_point'] 6029 else: 6030 if format_dict['thousands_sep'] is None: 6031 format_dict['thousands_sep'] = '' 6032 format_dict['grouping'] = [3, 0] 6033 format_dict['decimal_point'] = '.' 6034 5481 6035 # record whether return type should be str or unicode 5482 6036 format_dict['unicode'] = isinstance(format_spec, unicode) … … 5484 6038 return format_dict 5485 6039 5486 def _format_align(body, spec_dict): 5487 """Given an unpadded, non-aligned numeric string, add padding and 5488 aligment to conform with the given format specifier dictionary (as 5489 output from parse_format_specifier). 5490 5491 It's assumed that if body is negative then it starts with '-'. 5492 Any leading sign ('-' or '+') is stripped from the body before 5493 applying the alignment and padding rules, and replaced in the 5494 appropriate position. 6040 def _format_align(sign, body, spec): 6041 """Given an unpadded, non-aligned numeric string 'body' and sign 6042 string 'sign', add padding and alignment conforming to the given 6043 format specifier dictionary 'spec' (as produced by 6044 parse_format_specifier). 6045 6046 Also converts result to unicode if necessary. 5495 6047 5496 6048 """ 5497 # figure out the sign; we only examine the first character, so if5498 # body has leading whitespace the results may be surprising.5499 if len(body) > 0 and body[0] in '-+':5500 sign = body[0]5501 body = body[1:]5502 else:5503 sign = ''5504 5505 if sign != '-':5506 if spec_dict['sign'] in ' +':5507 sign = spec_dict['sign']5508 else:5509 sign = ''5510 5511 6049 # how much extra space do we have to play with? 5512 minimumwidth = spec _dict['minimumwidth']5513 fill = spec _dict['fill']5514 padding = fill*(m ax(minimumwidth - (len(sign+body)), 0))5515 5516 align = spec _dict['align']6050 minimumwidth = spec['minimumwidth'] 6051 fill = spec['fill'] 6052 padding = fill*(minimumwidth - len(sign) - len(body)) 6053 6054 align = spec['align'] 5517 6055 if align == '<': 5518 6056 result = sign + body + padding … … 5521 6059 elif align == '=': 5522 6060 result = sign + padding + body 5523 el se: #align == '^'6061 elif align == '^': 5524 6062 half = len(padding)//2 5525 6063 result = padding[:half] + sign + body + padding[half:] 6064 else: 6065 raise ValueError('Unrecognised alignment field') 5526 6066 5527 6067 # make sure that result is unicode if necessary 5528 if spec _dict['unicode']:6068 if spec['unicode']: 5529 6069 result = unicode(result) 5530 6070 5531 6071 return result 6072 6073 def _group_lengths(grouping): 6074 """Convert a localeconv-style grouping into a (possibly infinite) 6075 iterable of integers representing group lengths. 6076 6077 """ 6078 # The result from localeconv()['grouping'], and the input to this 6079 # function, should be a list of integers in one of the 6080 # following three forms: 6081 # 6082 # (1) an empty list, or 6083 # (2) nonempty list of positive integers + [0] 6084 # (3) list of positive integers + [locale.CHAR_MAX], or 6085 6086 from itertools import chain, repeat 6087 if not grouping: 6088 return [] 6089 elif grouping[-1] == 0 and len(grouping) >= 2: 6090 return chain(grouping[:-1], repeat(grouping[-2])) 6091 elif grouping[-1] == _locale.CHAR_MAX: 6092 return grouping[:-1] 6093 else: 6094 raise ValueError('unrecognised format for grouping') 6095 6096 def _insert_thousands_sep(digits, spec, min_width=1): 6097 """Insert thousands separators into a digit string. 6098 6099 spec is a dictionary whose keys should include 'thousands_sep' and 6100 'grouping'; typically it's the result of parsing the format 6101 specifier using _parse_format_specifier. 6102 6103 The min_width keyword argument gives the minimum length of the 6104 result, which will be padded on the left with zeros if necessary. 6105 6106 If necessary, the zero padding adds an extra '0' on the left to 6107 avoid a leading thousands separator. For example, inserting 6108 commas every three digits in '123456', with min_width=8, gives 6109 '0,123,456', even though that has length 9. 6110 6111 """ 6112 6113 sep = spec['thousands_sep'] 6114 grouping = spec['grouping'] 6115 6116 groups = [] 6117 for l in _group_lengths(grouping): 6118 if l <= 0: 6119 raise ValueError("group length should be positive") 6120 # max(..., 1) forces at least 1 digit to the left of a separator 6121 l = min(max(len(digits), min_width, 1), l) 6122 groups.append('0'*(l - len(digits)) + digits[-l:]) 6123 digits = digits[:-l] 6124 min_width -= l 6125 if not digits and min_width <= 0: 6126 break 6127 min_width -= len(sep) 6128 else: 6129 l = max(len(digits), min_width, 1) 6130 groups.append('0'*(l - len(digits)) + digits[-l:]) 6131 return sep.join(reversed(groups)) 6132 6133 def _format_sign(is_negative, spec): 6134 """Determine sign character.""" 6135 6136 if is_negative: 6137 return '-' 6138 elif spec['sign'] in ' +': 6139 return spec['sign'] 6140 else: 6141 return '' 6142 6143 def _format_number(is_negative, intpart, fracpart, exp, spec): 6144 """Format a number, given the following data: 6145 6146 is_negative: true if the number is negative, else false 6147 intpart: string of digits that must appear before the decimal point 6148 fracpart: string of digits that must come after the point 6149 exp: exponent, as an integer 6150 spec: dictionary resulting from parsing the format specifier 6151 6152 This function uses the information in spec to: 6153 insert separators (decimal separator and thousands separators) 6154 format the sign 6155 format the exponent 6156 add trailing '%' for the '%' type 6157 zero-pad if necessary 6158 fill and align if necessary 6159 """ 6160 6161 sign = _format_sign(is_negative, spec) 6162 6163 if fracpart: 6164 fracpart = spec['decimal_point'] + fracpart 6165 6166 if exp != 0 or spec['type'] in 'eE': 6167 echar = {'E': 'E', 'e': 'e', 'G': 'E', 'g': 'e'}[spec['type']] 6168 fracpart += "{0}{1:+}".format(echar, exp) 6169 if spec['type'] == '%': 6170 fracpart += '%' 6171 6172 if spec['zeropad']: 6173 min_width = spec['minimumwidth'] - len(fracpart) - len(sign) 6174 else: 6175 min_width = 0 6176 intpart = _insert_thousands_sep(intpart, spec, min_width) 6177 6178 return _format_align(sign, intpart+fracpart, spec) 6179 5532 6180 5533 6181 ##### Useful Constants (internal use only) ################################
Note:
See TracChangeset
for help on using the changeset viewer.