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

Guido van Rossum guido at python.org
Tue Mar 16 17:41:48 CET 2010


I'd say if you're not going to forward-port this to Python 3, it
shouldn't go into Python 2 -- in that case it would make more sense to
me to back-port the exception-raising behavior.

Also supporting comparisons but not other mixed operations is going to
be confusing. If you are sticking to that behavior I think mixed
comparisons should also be ruled out.

--Guido

On Tue, Mar 16, 2010 at 7:41 AM, Mark Dickinson <dickinsm at gmail.com> wrote:
> Hello all,
>
> Currently in Python 2.x, Decimal-to-float comparisons behave as follows:
>
>>>> Decimal(1) < float(4)
> False
>>>> Decimal(4) < float(1)
> False
>
> That is, any Decimal sorts before any float (though this is arbitrary:
>  it's possible that on some implementations any float sorts before any
> Decimal).  This causes (a) confusion, and (b) bugs, especially when
> floats and Decimals are accidentally combined in a program.  There
> probably aren't too many legitimate reasons for deliberately mixing
> floats and Decimals in the same calculation, so preventing accidents
> is the main concern here.
>
> In Python 3.x, however, such comparisons raise a TypeError
> ("unorderable types: Decimal() < float()").
>
> http://bugs.python.org/issue2531 ('float compared to decimal is
> silently incorrect') was opened for this a while ago.
>
> I'm planning to commit a change to trunk that changes the behaviour so
> that the comparison result is based on the respective values of the
> arguments (so the results above would be True and False respectively).
>
> Question for python-dev people (and the point of this email): should
> this change be forward ported to py3k?
>
> On the one hand there's something to be said for maintaining a clean
> separation between the float and Decimal types, allowing only explicit
> conversions from one to the other;  mixed-type arithmetic between
> floats and Decimals was very deliberately not permitted in the
> original PEP, and that's unlikely to change in a hurry.  On the other
> hand, there's value in keeping 2.x and 3.x aligned where possible for
> the sake of 2-to-3 porters, and the new behaviour may even be useful.
> Even with the TypeError above, there are still some py3k surprises
> arising from the ability to compare ints and Decimals, and ints and
> floats, but not floats and Decimals.
>
> A quick tour of some of these surprises, in trunk:
>
>>>> from decimal import Decimal
>>>> Decimal(1) < 2 < float(3) < Decimal(1)  # < is non-transitive
> True
>>>> Decimal(1) == 1 == float(1)   # so is equality
> True
>>>> Decimal(1) == float(1)
> False
>>>> d1, i1, f1 = Decimal(1), float(1), 1
>>>> set([d1, i1, f1]) == set([f1, i1, d1])  # sets with the same elements are different
> False
>>>> sorted([d1, i1, f1]) == sorted([f1, i1, d1])
> False
>
> and in py3k:
>
>>>> from decimal import Decimal
>>>> Decimal(1) < 2 < float(3) < Decimal(1)
> Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
> TypeError: unorderable types: float() < Decimal()
>>>> Decimal(1) == 1 == float(1)
> True
>>>> Decimal(1) == float(1)
> False
>>>> d1, i1, f1 = Decimal(1), float(1), 1
>>>> set([d1, i1, f1]) == set([f1, i1, d1])
> False
>>>> sorted([Decimal(1), 2, float(3)])
> [Decimal('1'), 2, 3.0]
>>>> sorted([2, Decimal(1), float(3)])
> Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
> TypeError: unorderable types: float() < Decimal()
>>>> sorted([float(3), 2, Decimal(1)])
> [Decimal('1'), 2, 3.0]
>
> By the way, even with the patch there are still problems with other
> numeric types: comparisons or set operations involving both Fraction
> and Decimal instances are going to cause similar difficulties to those
> above.  In practice I think this is much less of an issue than the
> float/Decimal problem, since the chance of accidentally combining
> Fraction and Decimal types in a calculation seems significantly
> smaller than the chance of accidentally combining float and Decimal
> types.
>
> --
> Mark
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org
>



-- 
--Guido van Rossum (python.org/~guido)


More information about the Python-Dev mailing list