This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: it seems that sorted built-in always return floats before int if they appear to be equal
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.8
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: johnmish.iam, steven.daprano
Priority: normal Keywords:

Created on 2021-04-19 11:48 by johnmish.iam, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg391372 - (view) Author: John Mish (johnmish.iam) Date: 2021-04-19 11:48
A1
>>> sorted([12.000000000000001, 2, 1.999, 2.1, 4, 12])
[1.999, 2, 2.1, 4, 12, 12.000000000000002]
A2
>>> sorted([12.0000000000000001, 2, 1.999, 2.1, 4, 12])
[1.999, 2, 2.1, 4, 12.0, 12]
B1
>>> sorted([11.999999999999999, 2, 1.999, 2.1, 4, 12])
[1.999, 2, 2.1, 4, 11.999999999999998, 12]
B2
>>> sorted([11.9999999999999999, 2, 1.999, 2.1, 4, 12])
[1.999, 2, 2.1, 4, 12.0, 12]

Hello,

In A2 and in B2 we see the same output for 2 not equal expected values.

It seems to be that floats are always first in list.

So, what about trying to "store" if some float is 12 "in limit" of 12 but from "left/-"? So then it is < than 12.

12.000000000000000000000000000001 would be then 12 but in upper limit, right/+ so > 12

What do You think?

Best regards.

PS ofc I could use decimal, but if it shouldn't work, why it does not raise exception and ask for forgiveness... ?
msg391375 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2021-04-19 12:41
Hi John, you said:

> it seems that sorted built-in always return floats before int if they appear to be equal

But that's not correct:

>>> sorted([5.0, 5])
[5.0, 5]
>>> sorted([5, 5.0])
[5, 5.0]


Python's sort is *stable*, which means that the order of two equal values will always be the same as before they were sorted.

You then ask:

> So, what about trying to "store" if some float is 12 "in limit" of 12 but from "left/-"? So then it is < than 12.


Short answer: no.

Longer answer: no, we're not going to complicate and slow down both floats and sorting in order to give "do what I mean" results for sorting.

What you are seeing is a fundamental limitation of floating point arithmetic. On the web, you can find dozens of sites that talk about this, in pretty much every single programming language with floating point numbers. You might like to start with the Python FAQ:

https://docs.python.org/3/faq/design.html#why-are-floating-point-calculations-so-inaccurate

In your case, you are being tripped up by the fact that there is no such float as either 11.9999999999999999 or 12.0000000000000001. Both of those are rounded to *exactly* 12.0, as the float data type only has (approximately) 17 decimal places of precision.

This is a fundamental feature of floating point numbers and there is nothing we can do about that without massively complicating and slowing down floats.

By the way, Decimal are floating point numbers too. They are equally affected by this, except that being stored in decimal with more digits by default, rather than binary, it is not so easy to trip over it. But it can certainly happen to Decimals as well.
msg391376 - (view) Author: John Mish (johnmish.iam) Date: 2021-04-19 13:21
Thanks, I should go deeper with it before filing. Wish You have great day Steven.
History
Date User Action Args
2022-04-11 14:59:44adminsetgithub: 88053
2021-04-19 13:21:30johnmish.iamsetmessages: + msg391376
2021-04-19 12:41:47steven.dapranosetstatus: open -> closed

nosy: + steven.daprano
messages: + msg391375

resolution: not a bug
stage: resolved
2021-04-19 11:48:23johnmish.iamcreate