[Python-Dev] Decimal <-> float comparisons in py3k.

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.from_float) 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