Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(33546)

Side by Side Diff: Lib/decimal.py

Issue 7652: Merge C version of decimal into py3k.
Patch Set: Created 7 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Include/longintrepr.h ('k') | Lib/test/support.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2004 Python Software Foundation. 1 # Copyright (c) 2004 Python Software Foundation.
2 # All rights reserved. 2 # All rights reserved.
3 3
4 # Written by Eric Price <eprice at tjhsst.edu> 4 # Written by Eric Price <eprice at tjhsst.edu>
5 # and Facundo Batista <facundo at taniquetil.com.ar> 5 # and Facundo Batista <facundo at taniquetil.com.ar>
6 # and Raymond Hettinger <python at rcn.com> 6 # and Raymond Hettinger <python at rcn.com>
7 # and Aahz <aahz at pobox.com> 7 # and Aahz <aahz at pobox.com>
8 # and Tim Peters 8 # and Tim Peters
9 9
10 # This module should be kept in sync with the latest updates of the 10 # This module should be kept in sync with the latest updates of the
(...skipping 28 matching lines...) Expand all
39 >>> from decimal import * 39 >>> from decimal import *
40 >>> setcontext(ExtendedContext) 40 >>> setcontext(ExtendedContext)
41 >>> Decimal(0) 41 >>> Decimal(0)
42 Decimal('0') 42 Decimal('0')
43 >>> Decimal('1') 43 >>> Decimal('1')
44 Decimal('1') 44 Decimal('1')
45 >>> Decimal('-.0123') 45 >>> Decimal('-.0123')
46 Decimal('-0.0123') 46 Decimal('-0.0123')
47 >>> Decimal(123456) 47 >>> Decimal(123456)
48 Decimal('123456') 48 Decimal('123456')
49 >>> Decimal('123.45e12345678901234567890') 49 >>> Decimal('123.45e12345678')
50 Decimal('1.2345E+12345678901234567892') 50 Decimal('1.2345E+12345680')
51 >>> Decimal('1.33') + Decimal('1.27') 51 >>> Decimal('1.33') + Decimal('1.27')
52 Decimal('2.60') 52 Decimal('2.60')
53 >>> Decimal('12.34') + Decimal('3.87') - Decimal('18.41') 53 >>> Decimal('12.34') + Decimal('3.87') - Decimal('18.41')
54 Decimal('-2.20') 54 Decimal('-2.20')
55 >>> dig = Decimal(1) 55 >>> dig = Decimal(1)
56 >>> print(dig / Decimal(3)) 56 >>> print(dig / Decimal(3))
57 0.333333333 57 0.333333333
58 >>> getcontext().prec = 18 58 >>> getcontext().prec = 18
59 >>> print(dig / Decimal(3)) 59 >>> print(dig / Decimal(3))
60 0.333333333333333333 60 0.333333333333333333
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 121
122 # Exceptions 122 # Exceptions
123 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero', 123 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
124 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow', 124 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
125 125
126 # Constants for use in setting up contexts 126 # Constants for use in setting up contexts
127 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING', 127 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
128 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 'ROUND_05UP', 128 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 'ROUND_05UP',
129 129
130 # Functions for manipulating contexts 130 # Functions for manipulating contexts
131 'setcontext', 'getcontext', 'localcontext' 131 'setcontext', 'getcontext', 'localcontext',
132
133 # Limits for the C version for compatibility
134 'MAX_PREC', 'MAX_EMAX', 'MIN_EMIN', 'MIN_ETINY',
135
136 # C version: compile time choice that enables the thread local context
137 'HAVE_THREADS'
132 ] 138 ]
133 139
134 __version__ = '1.70' # Highest version of the spec this complies with 140 __version__ = '1.70' # Highest version of the spec this complies with
135 # See http://speleotrove.com/decimal/ 141 # See http://speleotrove.com/decimal/
136 142
137 import copy as _copy 143 import copy as _copy
138 import math as _math 144 import math as _math
139 import numbers as _numbers 145 import numbers as _numbers
146 import sys
140 147
141 try: 148 try:
142 from collections import namedtuple as _namedtuple 149 from collections import namedtuple as _namedtuple
143 DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent') 150 DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent')
144 except ImportError: 151 except ImportError:
145 DecimalTuple = lambda *args: args 152 DecimalTuple = lambda *args: args
146 153
147 # Rounding 154 # Rounding
148 ROUND_DOWN = 'ROUND_DOWN' 155 ROUND_DOWN = 'ROUND_DOWN'
149 ROUND_HALF_UP = 'ROUND_HALF_UP' 156 ROUND_HALF_UP = 'ROUND_HALF_UP'
150 ROUND_HALF_EVEN = 'ROUND_HALF_EVEN' 157 ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
151 ROUND_CEILING = 'ROUND_CEILING' 158 ROUND_CEILING = 'ROUND_CEILING'
152 ROUND_FLOOR = 'ROUND_FLOOR' 159 ROUND_FLOOR = 'ROUND_FLOOR'
153 ROUND_UP = 'ROUND_UP' 160 ROUND_UP = 'ROUND_UP'
154 ROUND_HALF_DOWN = 'ROUND_HALF_DOWN' 161 ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
155 ROUND_05UP = 'ROUND_05UP' 162 ROUND_05UP = 'ROUND_05UP'
163
164 # Compatibility with the C version
165 HAVE_THREADS = True
166 if sys.maxsize == 2**63-1:
167 MAX_PREC = 999999999999999999
168 MAX_EMAX = 999999999999999999
169 MIN_EMIN = -999999999999999999
170 else:
171 MAX_PREC = 425000000
172 MAX_EMAX = 425000000
173 MIN_EMIN = -425000000
174
175 MIN_ETINY = MIN_EMIN - (MAX_PREC-1)
156 176
157 # Errors 177 # Errors
158 178
159 class DecimalException(ArithmeticError): 179 class DecimalException(ArithmeticError):
160 """Base exception class. 180 """Base exception class.
161 181
162 Used exceptions derive from this. 182 Used exceptions derive from this.
163 If an exception derives from another exception besides this (such as 183 If an exception derives from another exception besides this (such as
164 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only 184 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
165 called if the others are present. This isn't actually used for 185 called if the others are present. This isn't actually used for
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 392
373 # List of public traps and flags 393 # List of public traps and flags
374 _signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded, 394 _signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
375 Underflow, InvalidOperation, Subnormal] 395 Underflow, InvalidOperation, Subnormal]
376 396
377 # Map conditions (per the spec) to signals 397 # Map conditions (per the spec) to signals
378 _condition_map = {ConversionSyntax:InvalidOperation, 398 _condition_map = {ConversionSyntax:InvalidOperation,
379 DivisionImpossible:InvalidOperation, 399 DivisionImpossible:InvalidOperation,
380 DivisionUndefined:InvalidOperation, 400 DivisionUndefined:InvalidOperation,
381 InvalidContext:InvalidOperation} 401 InvalidContext:InvalidOperation}
402
403 # Valid rounding modes
404 _rounding_modes = (ROUND_DOWN, ROUND_HALF_UP, ROUND_HALF_EVEN, ROUND_CEILING,
405 ROUND_FLOOR, ROUND_UP, ROUND_HALF_DOWN, ROUND_05UP)
382 406
383 ##### Context Functions ################################################## 407 ##### Context Functions ##################################################
384 408
385 # The getcontext() and setcontext() function manage access to a thread-local 409 # The getcontext() and setcontext() function manage access to a thread-local
386 # current context. Py2.4 offers direct support for thread locals. If that 410 # current context. Py2.4 offers direct support for thread locals. If that
387 # is not available, use threading.current_thread() which is slower but will 411 # is not available, use threading.current_thread() which is slower but will
388 # work for older Pythons. If threads are not part of the build, create a 412 # work for older Pythons. If threads are not part of the build, create a
389 # mock threading object with threading.local() returning the module namespace. 413 # mock threading object with threading.local() returning the module namespace.
390 414
391 try: 415 try:
392 import threading 416 import threading
393 except ImportError: 417 except ImportError:
394 # Python was compiled without threads; create a mock object instead 418 # Python was compiled without threads; create a mock object instead
395 import sys
396 class MockThreading(object): 419 class MockThreading(object):
397 def local(self, sys=sys): 420 def local(self, sys=sys):
398 return sys.modules[__name__] 421 return sys.modules[__name__]
399 threading = MockThreading() 422 threading = MockThreading()
400 del sys, MockThreading 423 del MockThreading
401 424
402 try: 425 try:
403 threading.local 426 threading.local
404 427
405 except AttributeError: 428 except AttributeError:
406 429
407 # To fix reloading, force it to create a new context 430 # To fix reloading, force it to create a new context
408 # Old contexts have different exceptions in their dicts, making problems. 431 # Old contexts have different exceptions in their dicts, making problems.
409 if hasattr(threading.current_thread(), '__decimal_context__'): 432 if hasattr(threading.current_thread(), '__decimal_context__'):
410 del threading.current_thread().__decimal_context__ 433 del threading.current_thread().__decimal_context__
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 >>> Decimal.from_float(float('inf')) 700 >>> Decimal.from_float(float('inf'))
678 Decimal('Infinity') 701 Decimal('Infinity')
679 >>> Decimal.from_float(-float('inf')) 702 >>> Decimal.from_float(-float('inf'))
680 Decimal('-Infinity') 703 Decimal('-Infinity')
681 >>> Decimal.from_float(-0.0) 704 >>> Decimal.from_float(-0.0)
682 Decimal('-0') 705 Decimal('-0')
683 706
684 """ 707 """
685 if isinstance(f, int): # handle integer inputs 708 if isinstance(f, int): # handle integer inputs
686 return cls(f) 709 return cls(f)
687 if _math.isinf(f) or _math.isnan(f): # raises TypeError if not a float 710 if not isinstance(f, float):
711 raise TypeError("argument must be int or float.")
712 if _math.isinf(f) or _math.isnan(f):
688 return cls(repr(f)) 713 return cls(repr(f))
689 if _math.copysign(1.0, f) == 1.0: 714 if _math.copysign(1.0, f) == 1.0:
690 sign = 0 715 sign = 0
691 else: 716 else:
692 sign = 1 717 sign = 1
693 n, d = abs(f).as_integer_ratio() 718 n, d = abs(f).as_integer_ratio()
694 k = d.bit_length() - 1 719 k = d.bit_length() - 1
695 result = _dec_from_triple(sign, str(n*5**k), -k) 720 result = _dec_from_triple(sign, str(n*5**k), -k)
696 if cls is Decimal: 721 if cls is Decimal:
697 return result 722 return result
(...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1899 else: 1924 else:
1900 product = _dec_from_triple(self._sign ^ other._sign, 1925 product = _dec_from_triple(self._sign ^ other._sign,
1901 str(int(self._int) * int(other._int)), 1926 str(int(self._int) * int(other._int)),
1902 self._exp + other._exp) 1927 self._exp + other._exp)
1903 1928
1904 return product.__add__(third, context) 1929 return product.__add__(third, context)
1905 1930
1906 def _power_modulo(self, other, modulo, context=None): 1931 def _power_modulo(self, other, modulo, context=None):
1907 """Three argument version of __pow__""" 1932 """Three argument version of __pow__"""
1908 1933
1909 # if can't convert other and modulo to Decimal, raise 1934 other = _convert_other(other)
1910 # TypeError; there's no point returning NotImplemented (no 1935 if other is NotImplemented:
1911 # equivalent of __rpow__ for three argument pow) 1936 return other
1912 other = _convert_other(other, raiseit=True) 1937 modulo = _convert_other(modulo)
1913 modulo = _convert_other(modulo, raiseit=True) 1938 if modulo is NotImplemented:
1939 return modulo
1914 1940
1915 if context is None: 1941 if context is None:
1916 context = getcontext() 1942 context = getcontext()
1917 1943
1918 # deal with NaNs: if there are any sNaNs then first one wins, 1944 # deal with NaNs: if there are any sNaNs then first one wins,
1919 # (i.e. behaviour for NaNs is identical to that of fma) 1945 # (i.e. behaviour for NaNs is identical to that of fma)
1920 self_is_nan = self._isnan() 1946 self_is_nan = self._isnan()
1921 other_is_nan = other._isnan() 1947 other_is_nan = other._isnan()
1922 modulo_is_nan = modulo._isnan() 1948 modulo_is_nan = modulo._isnan()
1923 if self_is_nan or other_is_nan or modulo_is_nan: 1949 if self_is_nan or other_is_nan or modulo_is_nan:
(...skipping 1901 matching lines...) Expand 10 before | Expand all | Expand 10 after
3825 flags - When an exception is caused, flags[exception] is set. 3851 flags - When an exception is caused, flags[exception] is set.
3826 (Whether or not the trap_enabler is set) 3852 (Whether or not the trap_enabler is set)
3827 Should be reset by user of Decimal instance. 3853 Should be reset by user of Decimal instance.
3828 Emin - Minimum exponent 3854 Emin - Minimum exponent
3829 Emax - Maximum exponent 3855 Emax - Maximum exponent
3830 capitals - If 1, 1*10^1 is printed as 1E+1. 3856 capitals - If 1, 1*10^1 is printed as 1E+1.
3831 If 0, printed as 1e1 3857 If 0, printed as 1e1
3832 clamp - If 1, change exponents if too high (Default 0) 3858 clamp - If 1, change exponents if too high (Default 0)
3833 """ 3859 """
3834 3860
3835 def __init__(self, prec=None, rounding=None, 3861 def __init__(self, prec=None, rounding=None, Emin=None, Emax=None,
3836 traps=None, flags=None, 3862 capitals=None, clamp=None, flags=None, traps=None,
3837 Emin=None, Emax=None, 3863 _ignored_flags=None):
3838 capitals=None, clamp=None,
3839 _ignored_flags=None):
3840 # Set defaults; for everything except flags and _ignored_flags, 3864 # Set defaults; for everything except flags and _ignored_flags,
3841 # inherit from DefaultContext. 3865 # inherit from DefaultContext.
3842 try: 3866 try:
3843 dc = DefaultContext 3867 dc = DefaultContext
3844 except NameError: 3868 except NameError:
3845 pass 3869 pass
3846 3870
3847 self.prec = prec if prec is not None else dc.prec 3871 self.prec = prec if prec is not None else dc.prec
3848 self.rounding = rounding if rounding is not None else dc.rounding 3872 self.rounding = rounding if rounding is not None else dc.rounding
3849 self.Emin = Emin if Emin is not None else dc.Emin 3873 self.Emin = Emin if Emin is not None else dc.Emin
3850 self.Emax = Emax if Emax is not None else dc.Emax 3874 self.Emax = Emax if Emax is not None else dc.Emax
3851 self.capitals = capitals if capitals is not None else dc.capitals 3875 self.capitals = capitals if capitals is not None else dc.capitals
3852 self.clamp = clamp if clamp is not None else dc.clamp 3876 self.clamp = clamp if clamp is not None else dc.clamp
3853 3877
3854 if _ignored_flags is None: 3878 if _ignored_flags is None:
3855 self._ignored_flags = [] 3879 self._ignored_flags = []
3856 else: 3880 else:
3857 self._ignored_flags = _ignored_flags 3881 self._ignored_flags = _ignored_flags
3858 3882
3859 if traps is None: 3883 if traps is None:
3860 self.traps = dc.traps.copy() 3884 self.traps = dc.traps.copy()
3861 elif not isinstance(traps, dict): 3885 elif not isinstance(traps, dict):
3862 self.traps = dict((s, int(s in traps)) for s in _signals) 3886 self.traps = dict((s, int(s in traps)) for s in _signals + traps)
3863 else: 3887 else:
3864 self.traps = traps 3888 self.traps = traps
3865 3889
3866 if flags is None: 3890 if flags is None:
3867 self.flags = dict.fromkeys(_signals, 0) 3891 self.flags = dict.fromkeys(_signals, 0)
3868 elif not isinstance(flags, dict): 3892 elif not isinstance(flags, dict):
3869 self.flags = dict((s, int(s in flags)) for s in _signals) 3893 self.flags = dict((s, int(s in flags)) for s in _signals + flags)
3870 else: 3894 else:
3871 self.flags = flags 3895 self.flags = flags
3896
3897 def _set_integer_check(self, name, value, vmin, vmax):
3898 if not isinstance(value, int):
3899 raise TypeError("%s must be an integer" % name)
3900 if vmin == '-inf':
3901 if value > vmax:
3902 raise ValueError("%s must be in [%s, %d]. got: %s" % (name, vmin , vmax, value))
3903 elif vmax == 'inf':
3904 if value < vmin:
3905 raise ValueError("%s must be in [%d, %s]. got: %s" % (name, vmin , vmax, value))
3906 else:
3907 if value < vmin or value > vmax:
3908 raise ValueError("%s must be in [%d, %d]. got %s" % (name, vmin, vmax, value))
3909 return object.__setattr__(self, name, value)
3910
3911 def _set_signal_dict(self, name, d):
3912 if not isinstance(d, dict):
3913 raise TypeError("%s must be a signal dict" % d)
3914 for key in d:
3915 if not key in _signals:
3916 raise KeyError("%s is not a valid signal dict" % d)
3917 for key in _signals:
3918 if not key in d:
3919 raise KeyError("%s is not a valid signal dict" % d)
3920 return object.__setattr__(self, name, d)
3921
3922 def __setattr__(self, name, value):
3923 if name == 'prec':
3924 return self._set_integer_check(name, value, 1, 'inf')
3925 elif name == 'Emin':
3926 return self._set_integer_check(name, value, '-inf', 0)
3927 elif name == 'Emax':
3928 return self._set_integer_check(name, value, 0, 'inf')
3929 elif name == 'capitals':
3930 return self._set_integer_check(name, value, 0, 1)
3931 elif name == 'clamp':
3932 return self._set_integer_check(name, value, 0, 1)
3933 elif name == 'rounding':
3934 if not value in _rounding_modes:
3935 # raise TypeError even for strings to have consistency
3936 # among various implementations.
3937 raise TypeError("%s: invalid rounding mode" % value)
3938 return object.__setattr__(self, name, value)
3939 elif name == 'flags' or name == 'traps':
3940 return self._set_signal_dict(name, value)
3941 elif name == '_ignored_flags':
3942 return object.__setattr__(self, name, value)
3943 else:
3944 raise AttributeError(
3945 "'decimal.Context' object has no attribute '%s'" % name)
3946
3947 def __delattr__(self, name):
3948 raise AttributeError("%s cannot be deleted" % name)
3949
3950 # Support for pickling, copy, and deepcopy
3951 def __reduce__(self):
3952 flags = [sig for sig, v in self.flags.items() if v]
3953 traps = [sig for sig, v in self.traps.items() if v]
3954 return (self.__class__,
3955 (self.prec, self.rounding, self.Emin, self.Emax,
3956 self.capitals, self.clamp, flags, traps))
3872 3957
3873 def __repr__(self): 3958 def __repr__(self):
3874 """Show the current context.""" 3959 """Show the current context."""
3875 s = [] 3960 s = []
3876 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, ' 3961 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, '
3877 'Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d, ' 3962 'Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d, '
3878 'clamp=%(clamp)d' 3963 'clamp=%(clamp)d'
3879 % vars(self)) 3964 % vars(self))
3880 names = [f.__name__ for f, v in self.flags.items() if v] 3965 names = [f.__name__ for f, v in self.flags.items() if v]
3881 s.append('flags=[' + ', '.join(names) + ']') 3966 s.append('flags=[' + ', '.join(names) + ']')
3882 names = [t.__name__ for t, v in self.traps.items() if v] 3967 names = [t.__name__ for t, v in self.traps.items() if v]
3883 s.append('traps=[' + ', '.join(names) + ']') 3968 s.append('traps=[' + ', '.join(names) + ']')
3884 return ', '.join(s) + ')' 3969 return ', '.join(s) + ')'
3885 3970
3886 def clear_flags(self): 3971 def clear_flags(self):
3887 """Reset all flags to zero""" 3972 """Reset all flags to zero"""
3888 for flag in self.flags: 3973 for flag in self.flags:
3889 self.flags[flag] = 0 3974 self.flags[flag] = 0
3890 3975
3976 def clear_traps(self):
3977 """Reset all traps to zero"""
3978 for flag in self.traps:
3979 self.traps[flag] = 0
3980
3891 def _shallow_copy(self): 3981 def _shallow_copy(self):
3892 """Returns a shallow copy from self.""" 3982 """Returns a shallow copy from self."""
3893 nc = Context(self.prec, self.rounding, self.traps, 3983 nc = Context(self.prec, self.rounding, self.Emin, self.Emax,
3894 self.flags, self.Emin, self.Emax, 3984 self.capitals, self.clamp, self.flags, self.traps,
3895 self.capitals, self.clamp, self._ignored_flags) 3985 self._ignored_flags)
3896 return nc 3986 return nc
3897 3987
3898 def copy(self): 3988 def copy(self):
3899 """Returns a deep copy from self.""" 3989 """Returns a deep copy from self."""
3900 nc = Context(self.prec, self.rounding, self.traps.copy(), 3990 nc = Context(self.prec, self.rounding, self.Emin, self.Emax,
3901 self.flags.copy(), self.Emin, self.Emax, 3991 self.capitals, self.clamp,
3902 self.capitals, self.clamp, self._ignored_flags) 3992 self.flags.copy(), self.traps.copy(),
3993 self._ignored_flags)
3903 return nc 3994 return nc
3904 __copy__ = copy 3995 __copy__ = copy
3905 3996
3906 def _raise_error(self, condition, explanation = None, *args): 3997 def _raise_error(self, condition, explanation = None, *args):
3907 """Handles an error 3998 """Handles an error
3908 3999
3909 If the flag is in _ignored_flags, returns the default response. 4000 If the flag is in _ignored_flags, returns the default response.
3910 Otherwise, it sets the flag, then, if the corresponding 4001 Otherwise, it sets the flag, then, if the corresponding
3911 trap_enabler is set, it reraises the exception. Otherwise, it returns 4002 trap_enabler is set, it reraises the exception. Otherwise, it returns
3912 the default value after setting the flag. 4003 the default value after setting the flag.
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
4055 4146
4056 def canonical(self, a): 4147 def canonical(self, a):
4057 """Returns the same Decimal object. 4148 """Returns the same Decimal object.
4058 4149
4059 As we do not have different encodings for the same number, the 4150 As we do not have different encodings for the same number, the
4060 received object already is in its canonical form. 4151 received object already is in its canonical form.
4061 4152
4062 >>> ExtendedContext.canonical(Decimal('2.50')) 4153 >>> ExtendedContext.canonical(Decimal('2.50'))
4063 Decimal('2.50') 4154 Decimal('2.50')
4064 """ 4155 """
4156 if not isinstance(a, Decimal):
4157 raise TypeError("canonical requires a Decimal as an argument.")
4065 return a.canonical(context=self) 4158 return a.canonical(context=self)
4066 4159
4067 def compare(self, a, b): 4160 def compare(self, a, b):
4068 """Compares values numerically. 4161 """Compares values numerically.
4069 4162
4070 If the signs of the operands differ, a value representing each operand 4163 If the signs of the operands differ, a value representing each operand
4071 ('-1' if the operand is less than zero, '0' if the operand is zero or 4164 ('-1' if the operand is less than zero, '0' if the operand is zero or
4072 negative zero, or '1' if the operand is greater than zero) is used in 4165 negative zero, or '1' if the operand is greater than zero) is used in
4073 place of that operand for the comparison instead of the actual 4166 place of that operand for the comparison instead of the actual
4074 operand. 4167 operand.
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
4365 4458
4366 def is_canonical(self, a): 4459 def is_canonical(self, a):
4367 """Return True if the operand is canonical; otherwise return False. 4460 """Return True if the operand is canonical; otherwise return False.
4368 4461
4369 Currently, the encoding of a Decimal instance is always 4462 Currently, the encoding of a Decimal instance is always
4370 canonical, so this method returns True for any Decimal. 4463 canonical, so this method returns True for any Decimal.
4371 4464
4372 >>> ExtendedContext.is_canonical(Decimal('2.50')) 4465 >>> ExtendedContext.is_canonical(Decimal('2.50'))
4373 True 4466 True
4374 """ 4467 """
4468 if not isinstance(a, Decimal):
4469 raise TypeError("is_canonical requires a Decimal as an argument.")
4375 return a.is_canonical() 4470 return a.is_canonical()
4376 4471
4377 def is_finite(self, a): 4472 def is_finite(self, a):
4378 """Return True if the operand is finite; otherwise return False. 4473 """Return True if the operand is finite; otherwise return False.
4379 4474
4380 A Decimal instance is considered finite if it is neither 4475 A Decimal instance is considered finite if it is neither
4381 infinite nor a NaN. 4476 infinite nor a NaN.
4382 4477
4383 >>> ExtendedContext.is_finite(Decimal('2.50')) 4478 >>> ExtendedContext.is_finite(Decimal('2.50'))
4384 True 4479 True
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after
4957 -NaN 5052 -NaN
4958 -Infinity 5053 -Infinity
4959 -Normal 5054 -Normal
4960 -Subnormal 5055 -Subnormal
4961 -Zero 5056 -Zero
4962 +Zero 5057 +Zero
4963 +Subnormal 5058 +Subnormal
4964 +Normal 5059 +Normal
4965 +Infinity 5060 +Infinity
4966 5061
4967 >>> c = Context(ExtendedContext) 5062 >>> c = ExtendedContext.copy()
4968 >>> c.Emin = -999 5063 >>> c.Emin = -999
4969 >>> c.Emax = 999 5064 >>> c.Emax = 999
4970 >>> c.number_class(Decimal('Infinity')) 5065 >>> c.number_class(Decimal('Infinity'))
4971 '+Infinity' 5066 '+Infinity'
4972 >>> c.number_class(Decimal('1E-10')) 5067 >>> c.number_class(Decimal('1E-10'))
4973 '+Normal' 5068 '+Normal'
4974 >>> c.number_class(Decimal('2.50')) 5069 >>> c.number_class(Decimal('2.50'))
4975 '+Normal' 5070 '+Normal'
4976 >>> c.number_class(Decimal('0.1E-999')) 5071 >>> c.number_class(Decimal('0.1E-999'))
4977 '+Subnormal' 5072 '+Subnormal'
(...skipping 1095 matching lines...) Expand 10 before | Expand all | Expand 10 after
6073 format_dict['sign'] = '-' 6168 format_dict['sign'] = '-'
6074 6169
6075 # minimumwidth defaults to 0; precision remains None if not given 6170 # minimumwidth defaults to 0; precision remains None if not given
6076 format_dict['minimumwidth'] = int(format_dict['minimumwidth'] or '0') 6171 format_dict['minimumwidth'] = int(format_dict['minimumwidth'] or '0')
6077 if format_dict['precision'] is not None: 6172 if format_dict['precision'] is not None:
6078 format_dict['precision'] = int(format_dict['precision']) 6173 format_dict['precision'] = int(format_dict['precision'])
6079 6174
6080 # if format type is 'g' or 'G' then a precision of 0 makes little 6175 # if format type is 'g' or 'G' then a precision of 0 makes little
6081 # sense; convert it to 1. Same if format type is unspecified. 6176 # sense; convert it to 1. Same if format type is unspecified.
6082 if format_dict['precision'] == 0: 6177 if format_dict['precision'] == 0:
6083 if format_dict['type'] is None or format_dict['type'] in 'gG': 6178 if format_dict['type'] is None or format_dict['type'] in 'gGn':
6084 format_dict['precision'] = 1 6179 format_dict['precision'] = 1
6085 6180
6086 # determine thousands separator, grouping, and decimal separator, and 6181 # determine thousands separator, grouping, and decimal separator, and
6087 # add appropriate entries to format_dict 6182 # add appropriate entries to format_dict
6088 if format_dict['type'] == 'n': 6183 if format_dict['type'] == 'n':
6089 # apart from separators, 'n' behaves just like 'g' 6184 # apart from separators, 'n' behaves just like 'g'
6090 format_dict['type'] = 'g' 6185 format_dict['type'] = 'g'
6091 if _localeconv is None: 6186 if _localeconv is None:
6092 _localeconv = _locale.localeconv() 6187 _localeconv = _locale.localeconv()
6093 if format_dict['thousands_sep'] is not None: 6188 if format_dict['thousands_sep'] is not None:
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
6247 _NaN = Decimal('NaN') 6342 _NaN = Decimal('NaN')
6248 _Zero = Decimal(0) 6343 _Zero = Decimal(0)
6249 _One = Decimal(1) 6344 _One = Decimal(1)
6250 _NegativeOne = Decimal(-1) 6345 _NegativeOne = Decimal(-1)
6251 6346
6252 # _SignedInfinity[sign] is infinity w/ that sign 6347 # _SignedInfinity[sign] is infinity w/ that sign
6253 _SignedInfinity = (_Infinity, _NegativeInfinity) 6348 _SignedInfinity = (_Infinity, _NegativeInfinity)
6254 6349
6255 # Constants related to the hash implementation; hash(x) is based 6350 # Constants related to the hash implementation; hash(x) is based
6256 # on the reduction of x modulo _PyHASH_MODULUS 6351 # on the reduction of x modulo _PyHASH_MODULUS
6257 import sys
6258 _PyHASH_MODULUS = sys.hash_info.modulus 6352 _PyHASH_MODULUS = sys.hash_info.modulus
6259 # hash values to use for positive and negative infinities, and nans 6353 # hash values to use for positive and negative infinities, and nans
6260 _PyHASH_INF = sys.hash_info.inf 6354 _PyHASH_INF = sys.hash_info.inf
6261 _PyHASH_NAN = sys.hash_info.nan 6355 _PyHASH_NAN = sys.hash_info.nan
6262 del sys
6263 6356
6264 # _PyHASH_10INV is the inverse of 10 modulo the prime _PyHASH_MODULUS 6357 # _PyHASH_10INV is the inverse of 10 modulo the prime _PyHASH_MODULUS
6265 _PyHASH_10INV = pow(10, _PyHASH_MODULUS - 2, _PyHASH_MODULUS) 6358 _PyHASH_10INV = pow(10, _PyHASH_MODULUS - 2, _PyHASH_MODULUS)
6359 del sys
6266 6360
6361 try:
6362 import _decimal
6363 except ImportError:
6364 pass
6365 else:
6366 s1 = set(dir())
6367 s2 = set(dir(_decimal))
6368 for name in s1 - s2:
6369 del globals()[name]
6370 del s1, s2, name
6371 from _decimal import *
6267 6372
6268 if __name__ == '__main__': 6373 if __name__ == '__main__':
6269 import doctest, decimal 6374 import doctest, decimal
6270 doctest.testmod(decimal) 6375 doctest.testmod(decimal)
OLDNEW
« no previous file with comments | « Include/longintrepr.h ('k') | Lib/test/support.py » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+