简体   繁体   中英

Understanding Floating-point doc

I'm reading the Python doc about floating-point issues and limits .

About halfway down the page it says:

Interestingly, there are many different decimal numbers that share the same nearest approximate binary fraction. For example, the numbers 0.1 and 0.10000000000000001 and 0.1000000000000000055511151231257827021181583404541015625 are all approximated by 3602879701896397 / 2 ** 55. Since all of these decimal values share the same approximation, any one of them could be displayed while still preserving the invariant eval(repr(x)) == x .

In particular, what does it want to say with:

Since all of these decimal values share the same approximation, any one of them could be displayed while still preserving the invariant eval(repr(x)) == x

Doesn't Python truncate float with more than 15 decimal digits? Any examples?

The point is that you get the same output for repr() no matter how many extra digits were originally supplied,

>>> repr(0.1)
'0.1'
>>> repr(0.1000000000000000055511151231257827021181583404541015625)
'0.1'

So, why doesn't it print the longer version for both?

# Hypothetically...
>>> repr(0.1)
'0.1000000000000000055511151231257827021181583404541015625'
>>> repr(0.1000000000000000055511151231257827021181583404541015625)
'0.1000000000000000055511151231257827021181583404541015625'

So, there are multiple ways to print out the same number. Python uses the dtoa() function to choose the shortest way to print out a given number, and in this case, the shortest way is 0.1 .

0.1 isn't actually exact: the exact result is the longer one, but dtoa() rounds the number off when printing it out, as long as the rounded number will be rounded back to the original number when it is read back in. In other words,

float(repr(x)) == x

...even though both float() and repr() round their arguments.

In addition to Dietrich Epp's excellent answer, this answer specifically addresses the issue of "Doesn't Python truncate float with more than 15 decimal digits? Any examples?".

Consider the following Python session:

$ python
Python 2.7.5 (default, Oct  2 2013, 22:34:09) 
[GCC 4.8.1] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> x = 0.10000000000000001249000902703301107976585626602172851562500000000000000000000000000000000000000000000001
>>> x
0.10000000000000002
>>> y = 0.10000000000000001249000902703301107976585626602172851562500000000000000000000000000000000000000000000000
>>> y
0.1
>>> 

The literals assigned to x and y differ only in a very low significance digit - you will probably have to scroll to see it - yet x and y have different values. Obviously, that would not be the case if Python truncated based on 15 decimal digits.

Instead, it is picking the IEEE 64-bit binary floating point number closest to the decimal literal, with ties rounded to the one with a zero least significant fraction bit. I picked y to be exactly half way between two representable numbers, but rounding down. x is just a tiny bit bigger, so it rounds up.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM