gh-123497: New limit for Python integers on 64-bit platforms (GH-123724)

Instead of be limited just by the size of addressable memory (2**63
bytes), Python integers are now also limited by the number of bits, so
the number of bit now always fit in a 64-bit integer.

Both limits are much larger than what might be available in practice,
so it doesn't affect users.

_PyLong_NumBits() and _PyLong_Frexp() are now always successful.
This commit is contained in:
Serhiy Storchaka 2024-09-29 10:40:20 +03:00 committed by GitHub
parent e0a41a5dd1
commit d08c788822
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 108 additions and 175 deletions

View file

@ -406,19 +406,16 @@ float_richcompare(PyObject *v, PyObject *w, int op)
}
/* The signs are the same. */
/* Convert w to a double if it fits. In particular, 0 fits. */
uint64_t nbits64 = _PyLong_NumBits(w);
if (nbits64 > (unsigned int)DBL_MAX_EXP) {
int64_t nbits64 = _PyLong_NumBits(w);
assert(nbits64 >= 0);
assert(!PyErr_Occurred());
if (nbits64 > DBL_MAX_EXP) {
/* This Python integer is larger than any finite C double.
* Replace with little doubles
* that give the same outcome -- w is so large that
* its magnitude must exceed the magnitude of any
* finite float.
*/
if (nbits64 == (uint64_t)-1 && PyErr_Occurred()) {
/* This Python integer is so large that uint64_t isn't
* big enough to hold the # of bits. */
PyErr_Clear();
}
i = (double)vsign;
assert(wsign != 0);
j = wsign * 2.0;