Bizarre happenings in the world of Python. It seems that you are really not supposed to compare floating-point and decimal numbers, as this example shows:
Python 2.5.1 (r251:54863, Jan 17 2008, 19:35:17)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decimal import Decimal
>>> Decimal('1.0') > 2.0
False
>>> Decimal('3.0') > 2.0
False
>>> Decimal('1.0') < 2.0
True
>>> Decimal('3.0') < 2.0
True
>>> 2.0 < Decimal('1.0')
False
>>> 2.0 < Decimal('3.0')
False
>>> 2.0 > Decimal('1.0')
True
>>> 2.0 > Decimal('3.0')
True
But that’s not the end yet. I have NLTK 0.9.4 installed, and watch how truth is reversed if I simply import the NLTK package:
>>> import nltk
>>> Decimal('1.0') > 2.0
True
>>> Decimal('3.0') > 2.0
True
>>> Decimal('1.0') < 2.0
False
>>> Decimal('3.0') < 2.0
False
>>> 2.0 < Decimal('1.0')
True
>>> 2.0 < Decimal('3.0')
True
>>> 2.0 > Decimal('1.0')
False
>>> 2.0 > Decimal('3.0')
False
I’m filing bugs about this, but I do find this quite entertaining in a ‘oh-my-God-I-always-believed-Python-was-a-well-behaved-language’ sort of way.
Edit: Edward Loper from NLTK gave an explanation why this is the case — it’s not because of NLTK, but because of Python’s internal handling of the comparison operator on floating-point numbers:
Apparently, you’re only allowed to use comparison operators to compare
Decimalobjects to (i) otherDecimalobjects; (ii) integers; (iii) longs. Here, you’re comparing it to afloat, which isn’t allowed, as evidenced by the following:
>>> Decimal('.1').__cmp__(1)
-1
>>> Decimal('.1').__cmp__(.3)
NotImplemented
Since Decimal’s
__cmp__method returnsNotImplemented, python falls back on using.3‘s__cmp__method. Unfortunately, when you compare afloatto some random object, the results are pretty much arbitrary, and are not guaranteed to be consistent. [...]nltk’s not really playing much of a role here (other than tweaking the system to change that arbitrary result — my guess would be that the result depends on the pointer address of the
Decimalclass, or of some other object like that).
Crazy stuff.
