[issue27265] Hash of different, specific Decimals created from str is the same

Radosław Szalski report at bugs.python.org
Wed Jun 8 04:04:21 EDT 2016


New submission from Radosław Szalski:

Python 2.7.11 (default, May  9 2016, 19:53:39)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decimal import Decimal
>>> hash(Decimal('0.05')) == hash(Decimal('0.005'))
True
>>> hash(Decimal(0.05)) == hash(Decimal(0.005))
False

Interactive example: https://repl.it/CZUJ/6

Those values are numerically different and IMO should not have equal hashes. I am aware of the quirk with hash(-1) == hash(-2) which is at play here.
This only applies to Decimals created from strings as they are hashed differently than float-based ones.


What happens? The following equation is True:
>>> hash(Decimal('0.005')) == hash(Decimal('0.05'))

What I expected to happen? The following equation to be False:
>>> hash(Decimal('0.005')) == hash(Decimal('0.05'))


Platform: MacBook Pro Retina, 13", early 2015, OSX 10.11.5
Tested on Python Versions: 2.7.3, 2.7.10, 2.7.11 (installed via pyenv), all exhibit the same behavior


Relevant (not duplicate) issues I've found: 

http://bugs.python.org/issue10356 - decimal.py: hash of -1
http://bugs.python.org/issue8188 - Unified hash for numeric types.



---


Transcript of the interactive example: https://repl.it/CZUJ/6:

from decimal import Decimal

# These two different decimals have equal hashes
print(hash(Decimal('0.005')) == hash(Decimal('0.05')))

# Internally, Decimal's hash is computed like this (sign, exp + len(int), int)
print(hash((0, -2+len('5'), '5')) == hash((0, -3+len('5'), '5')))

# Removing constants, this becomes
print(hash(-2+len('5')) == hash(-3+len('5')))

# Which can be further simplified to:
print(hash(-1) == hash(-2))

# They both return -2, because at the CPython level, -1 is reserved for errors

# Whereas:
print(hash(Decimal(0.005)) == hash(Decimal(0.05)))

# And this is because Decimals created from floats are hashed as floats

----------
components: Library (Lib)
messages: 267802
nosy: Radosław Szalski, mark.dickinson
priority: normal
severity: normal
status: open
title: Hash of different, specific Decimals created from str is the same
type: behavior
versions: Python 2.7

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue27265>
_______________________________________


More information about the Python-bugs-list mailing list