From d77fedc745e659c893abce0165d73484502356fc Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Tue, 8 Jan 2008 21:42:03 +0000 Subject: [PATCH] Fix Decimal hash in Python 2.5 maintenance branch so that hash(x) == hash(int(x)) for any integral Decimal instance x. --- Lib/decimal.py | 8 +------- Lib/test/test_decimal.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Lib/decimal.py b/Lib/decimal.py index 3ee078f570..ebeb6d7208 100644 --- a/Lib/decimal.py +++ b/Lib/decimal.py @@ -800,13 +800,7 @@ class Decimal(object): 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((-1)**op.sign*op.int*10**op.exp) # The value of a nonzero nonspecial Decimal instance is # faithfully represented by the triple consisting of its sign, # its adjusted exponent, and its coefficient with trailing diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 46a448bf1f..34fc34ab94 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -961,6 +961,16 @@ class DecimalUsabilityTest(unittest.TestCase): # a value for which hash(n) != hash(n % (2**64-1)) # in Python pre-2.6 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 -- 2.50.1