diff options
author | Christian Heimes <christian@cheimes.de> | 2007-12-17 20:04:13 (GMT) |
---|---|---|
committer | Christian Heimes <christian@cheimes.de> | 2007-12-17 20:04:13 (GMT) |
commit | 2c1816160639f00489aa8bac6178e44bb51e7adb (patch) | |
tree | 2b0cf29416e1b6bacef23bf4c1736a464f864c19 /Lib/decimal.py | |
parent | 3377055486af6021e7662fc53f1504bd26981ea6 (diff) | |
download | cpython-2c1816160639f00489aa8bac6178e44bb51e7adb.zip cpython-2c1816160639f00489aa8bac6178e44bb51e7adb.tar.gz cpython-2c1816160639f00489aa8bac6178e44bb51e7adb.tar.bz2 |
Merged revisions 59512-59540 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r59513 | raymond.hettinger | 2007-12-15 01:07:25 +0100 (Sat, 15 Dec 2007) | 6 lines
Optimize PyList_AsTuple(). Improve cache performance by doing the
pointer copy and object increment in one pass. For small lists,
save the overhead of the call to memcpy() -- this comes up in
calls like f(*listcomp).
........
r59519 | christian.heimes | 2007-12-15 06:38:35 +0100 (Sat, 15 Dec 2007) | 2 lines
Fixed #1624: Remove output comparison for test_pep277
I had to modify Brett's patch slightly.
........
r59520 | georg.brandl | 2007-12-15 10:34:59 +0100 (Sat, 15 Dec 2007) | 2 lines
Add note about future import needed for with statement.
........
r59522 | georg.brandl | 2007-12-15 10:36:37 +0100 (Sat, 15 Dec 2007) | 2 lines
Argh, wrong version.
........
r59524 | georg.brandl | 2007-12-16 12:06:09 +0100 (Sun, 16 Dec 2007) | 2 lines
Dummy commit to investigate #1617.
........
r59525 | georg.brandl | 2007-12-16 12:21:48 +0100 (Sun, 16 Dec 2007) | 2 lines
Revert dummy commit now that the build slave is building.
........
r59527 | georg.brandl | 2007-12-16 16:47:46 +0100 (Sun, 16 Dec 2007) | 2 lines
Remove orphaned footnote reference.
........
r59528 | georg.brandl | 2007-12-16 16:53:49 +0100 (Sun, 16 Dec 2007) | 2 lines
Remove gratuitous unicode character.
........
r59529 | georg.brandl | 2007-12-16 16:59:19 +0100 (Sun, 16 Dec 2007) | 2 lines
Remove another unnecessary Unicode character.
........
r59530 | georg.brandl | 2007-12-16 17:00:36 +0100 (Sun, 16 Dec 2007) | 2 lines
Remove curious space-like characters.
........
r59532 | georg.brandl | 2007-12-16 20:36:51 +0100 (Sun, 16 Dec 2007) | 2 lines
Adapt conf.py to new option names.
........
r59533 | christian.heimes | 2007-12-16 22:39:43 +0100 (Sun, 16 Dec 2007) | 1 line
Fixed #1638: %zd configure test fails on Linux
........
r59536 | georg.brandl | 2007-12-17 00:11:16 +0100 (Mon, 17 Dec 2007) | 2 lines
Simplify.
........
r59537 | georg.brandl | 2007-12-17 00:13:29 +0100 (Mon, 17 Dec 2007) | 2 lines
Use PEP 8.
........
r59539 | georg.brandl | 2007-12-17 00:15:07 +0100 (Mon, 17 Dec 2007) | 2 lines
Don't use quotes for non-string code.
........
r59540 | facundo.batista | 2007-12-17 15:18:42 +0100 (Mon, 17 Dec 2007) | 4 lines
Removed the private _rounding_decision: it was not needed, and the code
is now simpler. Thanks Mark Dickinson.
........
Diffstat (limited to 'Lib/decimal.py')
-rw-r--r-- | Lib/decimal.py | 132 |
1 files changed, 38 insertions, 94 deletions
diff --git a/Lib/decimal.py b/Lib/decimal.py index ba335bb..b25f6e6 100644 --- a/Lib/decimal.py +++ b/Lib/decimal.py @@ -147,10 +147,6 @@ ROUND_UP = 'ROUND_UP' ROUND_HALF_DOWN = 'ROUND_HALF_DOWN' ROUND_05UP = 'ROUND_05UP' -# Rounding decision (not part of the public API) -NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY -ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end. - # Errors class DecimalException(ArithmeticError): @@ -932,9 +928,7 @@ class Decimal(_numbers.Real, _numbers.Inexact): if context is None: context = getcontext() - if context._rounding_decision == ALWAYS_ROUND: - return ans._fix(context) - return ans + return ans._fix(context) def __pos__(self, context=None): """Returns a copy, unless it is a sNaN. @@ -954,26 +948,23 @@ class Decimal(_numbers.Real, _numbers.Inexact): if context is None: context = getcontext() - if context._rounding_decision == ALWAYS_ROUND: - return ans._fix(context) - return ans + return ans._fix(context) - def __abs__(self, round=1, context=None): + def __abs__(self, round=True, context=None): """Returns the absolute value of self. - If the second argument is 0, do not round. + If the keyword argument 'round' is false, do not round. The + expression self.__abs__(round=False) is equivalent to + self.copy_abs(). """ + if not round: + return self.copy_abs() + if self._is_special: ans = self._check_nans(context=context) if ans: return ans - if not round: - if context is None: - context = getcontext() - context = context._shallow_copy() - context._set_rounding_decision(NEVER_ROUND) - if self._sign: ans = self.__neg__(context=context) else: @@ -1006,8 +997,6 @@ class Decimal(_numbers.Real, _numbers.Inexact): if other._isinfinity(): return Decimal(other) # Can't both be infinity here - shouldround = context._rounding_decision == ALWAYS_ROUND - exp = min(self._exp, other._exp) negativezero = 0 if context.rounding == ROUND_FLOOR and self._sign != other._sign: @@ -1019,33 +1008,29 @@ class Decimal(_numbers.Real, _numbers.Inexact): if negativezero: sign = 1 ans = _dec_from_triple(sign, '0', exp) - if shouldround: - ans = ans._fix(context) + ans = ans._fix(context) return ans if not self: exp = max(exp, other._exp - context.prec-1) ans = other._rescale(exp, context.rounding) - if shouldround: - ans = ans._fix(context) + ans = ans._fix(context) return ans if not other: exp = max(exp, self._exp - context.prec-1) ans = self._rescale(exp, context.rounding) - if shouldround: - ans = ans._fix(context) + ans = ans._fix(context) return ans op1 = _WorkRep(self) op2 = _WorkRep(other) - op1, op2 = _normalize(op1, op2, shouldround, context.prec) + op1, op2 = _normalize(op1, op2, context.prec) result = _WorkRep() if op1.sign != op2.sign: # Equal and opposite if op1.int == op2.int: ans = _dec_from_triple(negativezero, '0', exp) - if shouldround: - ans = ans._fix(context) + ans = ans._fix(context) return ans if op1.int < op2.int: op1, op2 = op2, op1 @@ -1070,8 +1055,7 @@ class Decimal(_numbers.Real, _numbers.Inexact): result.exp = op1.exp ans = Decimal(result) - if shouldround: - ans = ans._fix(context) + ans = ans._fix(context) return ans __radd__ = __add__ @@ -1128,34 +1112,29 @@ class Decimal(_numbers.Real, _numbers.Inexact): return Infsign[resultsign] resultexp = self._exp + other._exp - shouldround = context._rounding_decision == ALWAYS_ROUND # Special case for multiplying by zero if not self or not other: ans = _dec_from_triple(resultsign, '0', resultexp) - if shouldround: - # Fixing in case the exponent is out of bounds - ans = ans._fix(context) + # Fixing in case the exponent is out of bounds + ans = ans._fix(context) return ans # Special case for multiplying by power of 10 if self._int == '1': ans = _dec_from_triple(resultsign, other._int, resultexp) - if shouldround: - ans = ans._fix(context) + ans = ans._fix(context) return ans if other._int == '1': ans = _dec_from_triple(resultsign, self._int, resultexp) - if shouldround: - ans = ans._fix(context) + ans = ans._fix(context) return ans op1 = _WorkRep(self) op2 = _WorkRep(other) ans = _dec_from_triple(resultsign, str(op1.int * op2.int), resultexp) - if shouldround: - ans = ans._fix(context) + ans = ans._fix(context) return ans __rmul__ = __mul__ @@ -1292,8 +1271,7 @@ class Decimal(_numbers.Real, _numbers.Inexact): context._raise_error(InvalidOperation, 'x % 0')) quotient, remainder = self._divide(other, context) - if context._rounding_decision == ALWAYS_ROUND: - remainder = remainder._fix(context) + remainder = remainder._fix(context) return quotient, remainder def __rdivmod__(self, other, context=None): @@ -1327,8 +1305,7 @@ class Decimal(_numbers.Real, _numbers.Inexact): return context._raise_error(DivisionUndefined, '0 % 0') remainder = self._divide(other, context)[1] - if context._rounding_decision == ALWAYS_ROUND: - remainder = remainder._fix(context) + remainder = remainder._fix(context) return remainder def __rmod__(self, other, context=None): @@ -2498,9 +2475,7 @@ class Decimal(_numbers.Real, _numbers.Inexact): else: ans = self - if context._rounding_decision == ALWAYS_ROUND: - return ans._fix(context) - return ans + return ans._fix(context) def min(self, other, context=None): """Returns the smaller value. @@ -2534,9 +2509,7 @@ class Decimal(_numbers.Real, _numbers.Inexact): else: ans = other - if context._rounding_decision == ALWAYS_ROUND: - return ans._fix(context) - return ans + return ans._fix(context) def _isinteger(self): """Returns whether self is an integer""" @@ -3107,9 +3080,7 @@ class Decimal(_numbers.Real, _numbers.Inexact): else: ans = self - if context._rounding_decision == ALWAYS_ROUND: - return ans._fix(context) - return ans + return ans._fix(context) def min_mag(self, other, context=None): """Compares the values numerically with their sign ignored.""" @@ -3139,9 +3110,7 @@ class Decimal(_numbers.Real, _numbers.Inexact): else: ans = other - if context._rounding_decision == ALWAYS_ROUND: - return ans._fix(context) - return ans + return ans._fix(context) def next_minus(self, context=None): """Returns the largest representable number smaller than itself.""" @@ -3434,7 +3403,6 @@ class Context(object): Contains: prec - precision (for use in rounding, division, square roots..) rounding - rounding type (how you round) - _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round? traps - If traps[exception] = 1, then the exception is raised when it is caused. Otherwise, a value is substituted in. @@ -3450,7 +3418,6 @@ class Context(object): def __init__(self, prec=None, rounding=None, traps=None, flags=None, - _rounding_decision=None, Emin=None, Emax=None, capitals=None, _clamp=0, _ignored_flags=None): @@ -3488,16 +3455,16 @@ class Context(object): def _shallow_copy(self): """Returns a shallow copy from self.""" - nc = Context(self.prec, self.rounding, self.traps, self.flags, - self._rounding_decision, self.Emin, self.Emax, - self.capitals, self._clamp, self._ignored_flags) + nc = Context(self.prec, self.rounding, self.traps, + self.flags, self.Emin, self.Emax, + self.capitals, self._clamp, self._ignored_flags) return nc def copy(self): """Returns a deep copy from self.""" nc = Context(self.prec, self.rounding, self.traps.copy(), - self.flags.copy(), self._rounding_decision, self.Emin, - self.Emax, self.capitals, self._clamp, self._ignored_flags) + self.flags.copy(), self.Emin, self.Emax, + self.capitals, self._clamp, self._ignored_flags) return nc __copy__ = copy @@ -3554,27 +3521,6 @@ class Context(object): """Returns maximum exponent (= Emax - prec + 1)""" return int(self.Emax - self.prec + 1) - def _set_rounding_decision(self, type): - """Sets the rounding decision. - - Sets the rounding decision, and returns the current (previous) - rounding decision. Often used like: - - context = context._shallow_copy() - # That so you don't change the calling context - # if an error occurs in the middle (say DivisionImpossible is raised). - - rounding = context._set_rounding_decision(NEVER_ROUND) - instance = instance / Decimal(2) - context._set_rounding_decision(rounding) - - This will make it not round for that operation. - """ - - rounding = self._rounding_decision - self._rounding_decision = type - return rounding - def _set_rounding(self, type): """Sets the rounding type. @@ -4762,7 +4708,7 @@ class _WorkRep(object): -def _normalize(op1, op2, shouldround = 0, prec = 0): +def _normalize(op1, op2, prec = 0): """Normalizes op1, op2 to have the same exp and length of coefficient. Done during addition. @@ -4779,13 +4725,12 @@ def _normalize(op1, op2, shouldround = 0, prec = 0): # as adding any positive quantity smaller than 10**exp; similarly # for subtraction. So if other is smaller than 10**exp we replace # it with 10**exp. This avoids tmp.exp - other.exp getting too large. - if shouldround: - tmp_len = len(str(tmp.int)) - other_len = len(str(other.int)) - exp = tmp.exp + min(-1, tmp_len - prec - 2) - if other_len + other.exp - 1 < exp: - other.int = 1 - other.exp = exp + tmp_len = len(str(tmp.int)) + other_len = len(str(other.int)) + exp = tmp.exp + min(-1, tmp_len - prec - 2) + if other_len + other.exp - 1 < exp: + other.int = 1 + other.exp = exp tmp.int *= 10 ** (tmp.exp - other.exp) tmp.exp = other.exp @@ -5153,7 +5098,6 @@ DefaultContext = Context( prec=28, rounding=ROUND_HALF_EVEN, traps=[DivisionByZero, Overflow, InvalidOperation], flags=[], - _rounding_decision=ALWAYS_ROUND, Emax=999999999, Emin=-999999999, capitals=1 |