[Python-Dev] Decimal <-> float comparisons in py3k. (original) (raw)

Mark Dickinson dickinsm at gmail.com
Fri Mar 19 10:37:23 CET 2010


On Thu, Mar 18, 2010 at 9:48 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:

Note that even in Py3k there are some fairly serious weirdnesses kicking around due to the intransitive nature of numeric equality though:

Yep. My personal favourite is:

from decimal import Decimal as dec set((1, 1.0, dec(1))) == set((1.0, 1, dec(1))) False

(The sets even have different sizes!)

Note that while the originally proposed change does fix problems with sets of Decimals, ints and floats, and with sorting of lists of those types, it's not a complete fix: as soon as you throw Fractions into the mix, all the same problems arise again. Making hashes of int, float, Decimal and Fraction all compatible with one another, efficient for ints and floats, and not grossly inefficient for Fractions and Decimals, is kinda hairy, though I have a couple of ideas of how it could be done. Making Decimal-to-Fraction comparisons give correct results isn't easy either: the conversion in one direction (Fraction to Decimal) is lossy, while the conversion in the other direction (Decimal to Fraction) can't be performed efficiently if the Decimal has a large exponent (Decimal('1e123456')); so you can't just do the Decimal.from_float trick of whacking everything into a single domain and comparing there. Again, this is solvable, but not trivially so.

See, this is what happens when a language conflates numeric equality with the equivalence relation used for membership testing. ;-). (I'm not really complaining, but this is definitely one of the downsides of this particular design decision.)

When there is a clear, correct way (based on Decimal.fromfloat) to make numeric comparison behave in accordance with the rules of mathematics, do we really want to preserve strange, unintuitive behaviour like the above?

No. Not really, no. :)

Mark



More information about the Python-Dev mailing list