Commit d77fedc7 authored by Mark Dickinson's avatar Mark Dickinson

Fix Decimal hash in Python 2.5 maintenance branch so that hash(x) == hash(int(x))

for any integral Decimal instance x.
parent 5dfc4806
...@@ -800,13 +800,7 @@ class Decimal(object): ...@@ -800,13 +800,7 @@ class Decimal(object):
return 0 return 0
if self._isinteger(): if self._isinteger():
op = _WorkRep(self.to_integral_value()) op = _WorkRep(self.to_integral_value())
# to make computation feasible for Decimals with large return hash((-1)**op.sign*op.int*10**op.exp)
# 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))
# The value of a nonzero nonspecial Decimal instance is # The value of a nonzero nonspecial Decimal instance is
# faithfully represented by the triple consisting of its sign, # faithfully represented by the triple consisting of its sign,
# its adjusted exponent, and its coefficient with trailing # its adjusted exponent, and its coefficient with trailing
......
...@@ -961,6 +961,16 @@ class DecimalUsabilityTest(unittest.TestCase): ...@@ -961,6 +961,16 @@ class DecimalUsabilityTest(unittest.TestCase):
# a value for which hash(n) != hash(n % (2**64-1)) # a value for which hash(n) != hash(n % (2**64-1))
# in Python pre-2.6 # in Python pre-2.6
Decimal(2**64 + 2**32 - 1), Decimal(2**64 + 2**32 - 1),
# selection of values which fail with the Python 2.6
# version of Decimal.__hash__ and the Python 2.5
# version of long.__hash__. Included here to prevent
# an accidental backport of the Decimal.__hash__ from
# Python 2.6 to Python 2.5.
Decimal("1.634E100"),
Decimal("90.697E100"),
Decimal("188.83E100"),
Decimal("1652.9E100"),
Decimal("56531E100"),
]) ])
# check that hash(d) == hash(int(d)) for integral values # check that hash(d) == hash(int(d)) for integral values
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment