4 ms·
The first significant digit of "0.1" and "0.2" _is_ 3! The first significant digit of "0.3" just isn't 3. In case anyone hasn't seen it yet, if you print a dou
by bla3 3y ago
The first significant digit of "0.1" and "0.2" _is_ 3! The first significant digit of "0.3" just isn't 3.
In case anyone hasn't seen it yet, if you print a double with enough fractional values, you'll eventually get its "true" value (because 2 divides 10).
>>> print('%.60f' % 0.1)
0.100000000000000005551115123125782702118158340454101562500000
It's only zeros after these zeros.
Here are the "true" values of 0.2, 0.3, and their sum:
>>> print('%.60f' % 0.2)
0.200000000000000011102230246251565404236316680908203125000000
>>> print('%.60f' % 0.3)
0.299999999999999988897769753748434595763683319091796875000000
>>> print('%.60f' % (0.1 + 0.2))
0.300000000000000044408920985006261616945266723632812500000000
Turns out 0.1 + 0.2 is actually the number right after "0.3":
>>> print('%.60f' % math.nextafter(0.3, 100))
0.300000000000000044408920985006261616945266723632812500000000
If you don't use a ton of decimal digits, by default the runtime prints the shortest decimal number that has the same binary representation as the true value when converting that decimal number to binary. Much of the confusion around floats is due to that convenience feature that aims to make floats less confusing.
- eru 3y ago> If you don't use a ton of decimal digits, by default the runtime prints the shortest decimal number that has the same binary representation as the true value when converting that decimal number to binary. The algorithm to do this efficiently is quite interesting, too.