Issue #1772851. Optimization of __hash__ to behave better for big big

numbers.
This commit is contained in:
Facundo Batista 2007-09-19 17:53:25 +00:00
parent ae406c6018
commit 8c20244069
2 changed files with 43 additions and 4 deletions

View file

@ -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):