>>> import decimal >>> decimal.Decimal('0.2') < 0.3 False >>> |
This little gem took me two hours to track down.
It turns out that since my code is using sqlobject, it also uses the decimal module. I had some constants set up, and from within some larger algorithm I wanted to compare values extracted from the db to those constants. However, my code didn’t seem to work, and I was sure the problem lay somewhere else in the algorithm.
Two hours later, and I found this comparison. It might be similar to this issue, but I’m not sure.
In any case, I was using Python 2.5.2, and decimal works as expected in Python 2.6, so I guess it is indeed time for an upgrade.
After some more checking with Python 2.6, it seems that:
>>> decimal.Decimal('0.6') < 0.3 True |
Not good.
It doesn’t have anything todo with that issue.
I am really dumbstruck how they released a module with such bugs.
I suggest you to install python on a clean machine and check it out again.
This is indeed a pain. The fix is to do:
float(decimal.Decimal(‘0.2’) < 0.3)
Obviously this isn’t ideal though. The reasons for this are down to the differences precision in floats and decimals. There’s an explanation for it in this patch for python 3000:
http://mail.python.org/pipermail/python-3000-checkins/2008-November/004843.html
“Comparison of objects of the differing types depends on whether either
of the types provide explicit support for the comparison. Most numberic types
can be compared with one another, but comparisons of :class:`float` and
:class:`Decimal` are not supported to avoid the inevitable confusion arising
from representation issues such as “float(‘1.1’)“ being inexactly represented
and therefore not exactly equal to “Decimal(‘1.1’)“ which is. When
cross-type comparison is not supported, the comparison method returns
“NotImplemented“. This can create the illusion of non-transitivity between
supported cross-type comparisons and unsupported comparisons. For example,
“Decimal(2) == 2“ and `2 == float(2)“ but “Decimal(2) != float(2)“.”
Small typo in the above:
float(decimal.Decimal(‘0.2’) < 0.3)
Should be:
float(decimal.Decimal(‘0.2’)) < 0.3
It seems Issue 2531 references this bug. I don’t think it should have been rejected, as this behavior is problematic, and was also “declared incorrect” in Python 3.