diff options
author | Raymond Hettinger <python@rcn.com> | 2004-08-17 06:39:37 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2004-08-17 06:39:37 (GMT) |
commit | d6c700a320eacd6f04cbcc60996b84e765766890 (patch) | |
tree | d07c64797ec5e9cfce7464a8f9fdc60b1d78351c /Lib/decimal.py | |
parent | f63ba43733aca984272540040d43ddf0c3fbdae9 (diff) | |
download | cpython-d6c700a320eacd6f04cbcc60996b84e765766890.zip cpython-d6c700a320eacd6f04cbcc60996b84e765766890.tar.gz cpython-d6c700a320eacd6f04cbcc60996b84e765766890.tar.bz2 |
Revise max() and min() to comply with the 8/2/2004 update to the specification
(version 1.45):
The max and min operations follow the rules in the current IEEE 754 revision draft:
if one operand is a quiet NaN and the other is number, then the number is always returned
if both operands are finite and equal in numerical value then an ordering is applied:
if the signs differ then max returns the operand with the positive sign and
min returns the operand with the negative sign; if the signs are the same then
the exponent is used to select the result.
Diffstat (limited to 'Lib/decimal.py')
-rw-r--r-- | Lib/decimal.py | 84 |
1 files changed, 65 insertions, 19 deletions
diff --git a/Lib/decimal.py b/Lib/decimal.py index 101e5d8..63f9991 100644 --- a/Lib/decimal.py +++ b/Lib/decimal.py @@ -2032,17 +2032,39 @@ class Decimal(object): context = getcontext() other = self._convert_other(other) - ans = self._check_nans(other, context) - if ans: - return ans + # if one operand is a quiet NaN and the other is number, then the + # number is always returned + sn = self._isnan() + on = other._isnan() + if sn or on: + if on == 1 and sn != 2: + return self + if sn == 1 and on != 2: + return other + return self._check_nans(other, context) ans = self - if self < other: + c = self.__cmp__(other) + if c == 0: + # if both operands are finite and equal in numerical value + # then an ordering is applied: + # + # if the signs differ then max returns the operand with the + # positive sign and min returns the operand with the negative sign + # + # if the signs are the same then the exponent is used to select + # the result. + if self._sign != other._sign: + if self._sign: + ans = other + elif self._exp < other._exp and not self._sign: + ans = other + elif self._exp > other._exp and self._sign: + ans = other + elif c == -1: ans = other - shouldround = context._rounding_decision == ALWAYS_ROUND - if shouldround: - ans = ans._fix(context=context) - return ans + context._rounding_decision == ALWAYS_ROUND + return ans._fix(context=context) def min(self, other, context=None): """Returns the smaller value. @@ -2054,19 +2076,39 @@ class Decimal(object): context = getcontext() other = self._convert_other(other) - ans = self._check_nans(other, context) - if ans: - return ans + # if one operand is a quiet NaN and the other is number, then the + # number is always returned + sn = self._isnan() + on = other._isnan() + if sn or on: + if on == 1 and sn != 2: + return self + if sn == 1 and on != 2: + return other + return self._check_nans(other, context) ans = self - - if self > other: + c = self.__cmp__(other) + if c == 0: + # if both operands are finite and equal in numerical value + # then an ordering is applied: + # + # if the signs differ then max returns the operand with the + # positive sign and min returns the operand with the negative sign + # + # if the signs are the same then the exponent is used to select + # the result. + if self._sign != other._sign: + if other._sign: + ans = other + elif self._exp > other._exp and not self._sign: + ans = other + elif self._exp < other._exp and self._sign: + ans = other + elif c == 1: ans = other - - if context._rounding_decision == ALWAYS_ROUND: - ans = ans._fix(context=context) - - return ans + context._rounding_decision == ALWAYS_ROUND + return ans._fix(context=context) def _isinteger(self): """Returns whether self is an integer""" @@ -2397,7 +2439,9 @@ class Context(object): >>> ExtendedContext.max(Decimal('-10'), Decimal('3')) Decimal("3") >>> ExtendedContext.max(Decimal('1.0'), Decimal('1')) - Decimal("1.0") + Decimal("1") + >>> ExtendedContext.max(Decimal('7'), Decimal('NaN')) + Decimal("7") """ return a.max(b, context=self) @@ -2416,6 +2460,8 @@ class Context(object): Decimal("-10") >>> ExtendedContext.min(Decimal('1.0'), Decimal('1')) Decimal("1.0") + >>> ExtendedContext.min(Decimal('7'), Decimal('NaN')) + Decimal("7") """ return a.min(b, context=self) |