Since zeros are skipped when displaying the base
I like to look at my favorite reference implementation for such questions.
Evidence
In the comments, Casevh has a great intuition. Here's the corresponding code :
for (bits_per_char = -1; n; ++bits_per_char) n >>= 1; while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base) ++p; *str = p; n = (p - start) * bits_per_char + PyLong_SHIFT - 1; if (n / bits_per_char < p - start) { PyErr_SetString(PyExc_ValueError,"long string too large to convert"); return NULL;
Where p initially set to a pointer to your string. If we look at the PyLongDigitValue table, we will see that 0 is explicitly mapped to 0.
Python does a lot of extra work to optimize the conversion of certain bases ( there is an interesting comment on 200 lines about converting binary !), Which is why it does a lot of work to bring out the correct base in the first place. In this case; we can skip zeros when displaying the base, so they are not taken into account when calculating the overflow.
Indeed, we check how many bits are needed to store this float, but python is smart enough to remove zero leading zeros from it. I do not see anything in the float function documents guaranteeing this behavior in all implementations. They sinisterly declare
Convert a string or number to a floating point number, if possible.
When it does not work
When you write
float("0." + "0"*(2**32))
It stops database parsing at an early stage - all other zeros are considered in calculating bit lengths and contribute to raising ValueError
Similar analytic tricks
Here's a similar case in the float class, where we find that spaces are ignored (and an interesting comment by the authors about their intention with this design choice)
while (Py_ISSPACE(*s)) s++;
en_Knight
source share