[Python-checkins] r59852 - in python/trunk: Lib/decimal.py Lib/test/test_decimal.py Misc/NEWS

facundo.batista python-checkins at python.org
Tue Jan 8 13:25:21 CET 2008


Author: facundo.batista
Date: Tue Jan 8 13:25:20 2008
New Revision: 59852
Modified:
 python/trunk/Lib/decimal.py
 python/trunk/Lib/test/test_decimal.py
 python/trunk/Misc/NEWS
Log:
Issue #1757: The hash of a Decimal instance is no longer affected
by the current context. Thanks Mark Dickinson.
Modified: python/trunk/Lib/decimal.py
==============================================================================
--- python/trunk/Lib/decimal.py	(original)
+++ python/trunk/Lib/decimal.py	Tue Jan 8 13:25:20 2008
@@ -788,8 +788,10 @@
 def __hash__(self):
 """x.__hash__() <==> hash(x)"""
 # Decimal integers must hash the same as the ints
- # Non-integer decimals are normalized and hashed as strings
- # Normalization assures that hash(100E-1) == hash(10)
+ #
+ # The hash of a nonspecial noninteger Decimal must depend only
+ # on the value of that Decimal, and not on its representation.
+ # For example: hash(Decimal("100E-1")) == hash(Decimal("10")).
 if self._is_special:
 if self._isnan():
 raise TypeError('Cannot hash a NaN value.')
@@ -805,7 +807,13 @@
 # 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()))
+ # 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
+ # zeros removed.
+ return hash((self._sign,
+ self._exp+len(self._int),
+ self._int.rstrip('0')))
 
 def as_tuple(self):
 """Represents the number as a triple tuple.
Modified: python/trunk/Lib/test/test_decimal.py
==============================================================================
--- python/trunk/Lib/test/test_decimal.py	(original)
+++ python/trunk/Lib/test/test_decimal.py	Tue Jan 8 13:25:20 2008
@@ -980,6 +980,23 @@
 self.assert_(hash(Decimal('Inf')))
 self.assert_(hash(Decimal('-Inf')))
 
+ # check that the value of the hash doesn't depend on the
+ # current context (issue #1757)
+ c = getcontext()
+ old_precision = c.prec
+ x = Decimal("123456789.1")
+
+ c.prec = 6
+ h1 = hash(x)
+ c.prec = 10
+ h2 = hash(x)
+ c.prec = 16
+ h3 = hash(x)
+
+ self.assertEqual(h1, h2)
+ self.assertEqual(h1, h3)
+ c.prec = old_precision
+
 def test_min_and_max_methods(self):
 
 d1 = Decimal('15.32')
Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Tue Jan 8 13:25:20 2008
@@ -348,6 +348,9 @@
 Library
 -------
 
+- Issue #1757: The hash of a Decimal instance is no longer affected by
+ the current context.
+
 - Patch #467924: add ZipFile.extract() and ZipFile.extractall() in the
 zipfile module.
 


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /