Python doesn't exactly convert an integer to a float; it converts a float to an integer:
>>> 9007199254740993 == int(9007199254740993.0) False
This is not so, because int (9007199254740993.0) is actually 9007199254740992:
>>> 9007199254740992 == 9007199254740993.0 True
See the float_richcompare() function . In particular, a comment before him:
What happens for these two numbers:
- Python tries to use the
int.__eq__(float) route, but returns NotImplemented - Python tries to use the
float.__eq__(int) route, which handles float_richcompare() .
In this function v is your float, w is an integer. The following is a selection of code that runs for this path:
else if (PyLong_Check(w)) { nbits = _PyLong_NumBits(w); if (nbits <= 48) { } (void) frexp(i, &exponent); if (exponent < 0 || (size_t)exponent < nbits) { } if ((size_t)exponent > nbits) { } { r = PyObject_RichCompareBool(vv, ww, op); result = PyBool_FromLong(r); return result; }
So in the end, due to the size of the numbers involved, Python converts the float to an integer, and it is this conversion where the floating point number turns out to be 9007199254740992 . This is because the float cannot accurately express 9007199254740993.0 exactly:
>>> 9007199254740993.0 9007199254740992.0
Martijn pieters
source share