Description
Bug report
Running sys.float_info
shows that the smallest number a float can store is min_10_exp=-307
. However, by trial and error, it turns out that the true minimum value is 10.0 ** -323
>>> import sys
>>> sys.float_info
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)
>>> 10.0 ** -323
1e-323
>>> 10.0 ** -324
0.0
Therefore, min_10_exp=-307
should be corrected to min_10_exp=-323
.
The same apply for min
, it should be:
>>> f"{pow(10.0, -323):.16}"
'9.881312916824931e-324'
The max value is correct:
>>> 10.0 ** 308
1e+308
>>> 10.0 ** 309
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: (34, 'Numerical result out of range')
It turns out that a lot of information provided by this attribute(float_info
) is not correct, the correct ones are:
>>> 2.0 ** 1023
8.98846567431158e+307
# this implies that max=8.98846567431158e+307 and max_exp=1023
# max_10_exp=308 is correct
>>> f"{pow(2.0, -1074):.16}"
'4.940656458412465e-324'
# this implies that min=4.940656458412465e-324 and min_exp=1074
Following the 64bits version of IEEE 754 standard, the sign is coded on 1 bit, the exponent on 11 bit, and 52-bit for the mantissa, 11 + 1 + 52 = 64 bits; the precision being 52 bits, thus 15 significant digits. This means that dig=15
is correct and mant_dig=52
instead of mant_dig=53
.
|-63-|62-----------52|51------------------------0|
|sign|---exponent----|---------mantissa----------|
|1bit|----11bits-----|----------52bits-----------|
Your environment
- CPython versions tested on: Python 3.9.10
- Operating system and architecture: Ubuntu 20.04.4 LTS 64 bits.