diff options
author | Facundo Batista <facundobatista@gmail.com> | 2007-09-19 17:53:25 (GMT) |
---|---|---|
committer | Facundo Batista <facundobatista@gmail.com> | 2007-09-19 17:53:25 (GMT) |
commit | 8c202440699cef19602acc24822366d0d7c32083 (patch) | |
tree | c8dbd3260c57ba194db7aed972a3709da66b6e2c /Lib/decimal.py | |
parent | ae406c60180fbaa6d30b82ec2174ea38f9ba746f (diff) | |
download | cpython-8c202440699cef19602acc24822366d0d7c32083.zip cpython-8c202440699cef19602acc24822366d0d7c32083.tar.gz cpython-8c202440699cef19602acc24822366d0d7c32083.tar.bz2 |
Issue #1772851. Optimization of __hash__ to behave better for big big
numbers.
Diffstat (limited to 'Lib/decimal.py')
-rw-r--r-- | Lib/decimal.py | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/Lib/decimal.py b/Lib/decimal.py index 4137d06..6ca8bab 100644 --- a/Lib/decimal.py +++ b/Lib/decimal.py @@ -766,10 +766,17 @@ class Decimal(object): if self._isnan(): raise TypeError('Cannot hash a NaN value.') return hash(str(self)) - i = int(self) - if self == Decimal(i): - return hash(i) - assert self.__nonzero__() # '-0' handled by integer case + if not self: + return 0 + if self._isinteger(): + op = _WorkRep(self.to_integral_value()) + # to make computation feasible for Decimals with large + # exponent, we use the fact that hash(n) == hash(m) for + # any two nonzero integers n and m such that (i) n and m + # have the same sign, and (ii) n is congruent to m modulo + # 2**64-1. So we can replace hash((-1)**s*c*10**e) with + # hash((-1)**s*c*pow(10, e, 2**64-1). + return hash((-1)**op.sign*op.int*pow(10, op.exp, 2**64-1)) return hash(str(self.normalize())) def as_tuple(self): |