mirror of
https://github.com/python/cpython.git
synced 2026-01-29 02:32:18 +00:00
Fix Decimal hash in Python 2.5 maintenance branch so that hash(x) == hash(int(x))
for any integral Decimal instance x.
This commit is contained in:
parent
5dfc48060b
commit
d77fedc745
2 changed files with 11 additions and 7 deletions
|
|
@ -800,13 +800,7 @@ def __hash__(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((-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
|
||||
|
|
|
|||
|
|
@ -961,6 +961,16 @@ def test_hash_method(self):
|
|||
# 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue