summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFacundo Batista <facundobatista@gmail.com>2007-12-17 14:18:42 (GMT)
committerFacundo Batista <facundobatista@gmail.com>2007-12-17 14:18:42 (GMT)
commite64acfad3dd13809943eecf50f11c40c510dedbe (patch)
tree781fed23c31b826bbf96f1949d26c4bfa28c0182
parentd41b8dc58cc90c96af5be57b3edbcdc4fa98738c (diff)
downloadcpython-e64acfad3dd13809943eecf50f11c40c510dedbe.zip
cpython-e64acfad3dd13809943eecf50f11c40c510dedbe.tar.gz
cpython-e64acfad3dd13809943eecf50f11c40c510dedbe.tar.bz2
Removed the private _rounding_decision: it was not needed, and the code
is now simpler. Thanks Mark Dickinson.
-rw-r--r--Lib/decimal.py132
1 files changed, 38 insertions, 94 deletions
diff --git a/Lib/decimal.py b/Lib/decimal.py
index ee65b12..882c3a2 100644
--- a/Lib/decimal.py
+++ b/Lib/decimal.py
@@ -146,10 +146,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):
@@ -911,9 +907,7 @@ class Decimal(object):
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.
@@ -933,26 +927,23 @@ class Decimal(object):
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:
@@ -985,8 +976,6 @@ class Decimal(object):
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:
@@ -998,33 +987,29 @@ class Decimal(object):
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
@@ -1049,8 +1034,7 @@ class Decimal(object):
result.exp = op1.exp
ans = Decimal(result)
- if shouldround:
- ans = ans._fix(context)
+ ans = ans._fix(context)
return ans
__radd__ = __add__
@@ -1107,34 +1091,29 @@ class Decimal(object):
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__
@@ -1274,8 +1253,7 @@ class Decimal(object):
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):
@@ -1309,8 +1287,7 @@ class Decimal(object):
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):
@@ -2487,9 +2464,7 @@ class Decimal(object):
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.
@@ -2523,9 +2498,7 @@ class Decimal(object):
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"""
@@ -3096,9 +3069,7 @@ class Decimal(object):
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."""
@@ -3128,9 +3099,7 @@ class Decimal(object):
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."""
@@ -3423,7 +3392,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.
@@ -3439,7 +3407,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):
@@ -3479,16 +3446,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
@@ -3545,27 +3512,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.
@@ -4753,7 +4699,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.
@@ -4770,13 +4716,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
@@ -5144,7 +5089,6 @@ DefaultContext = Context(
prec=28, rounding=ROUND_HALF_EVEN,
traps=[DivisionByZero, Overflow, InvalidOperation],
flags=[],
- _rounding_decision=ALWAYS_ROUND,
Emax=999999999,
Emin=-999999999,
capitals=1