简体   繁体   English

了解浮点文档

[英]Understanding Floating-point doc

I'm reading the Python doc about floating-point issues and limits . 我正在阅读有关浮点数问题和限制的Python文档。

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 . 例如,数字0.1和0.10000000000000001和0.10000000000000000555111512312578270211815834045410102525均由3602879701896397/2 ** 55近似。由于所有这些十进制值都具有相同的近似值,因此可以显示其中任何一个,同时仍保留不变的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 由于所有这些十进制值都具有相同的近似值,因此可以显示其中任何一个,同时仍保留不变的eval(repr(x)) == x

Doesn't Python truncate float with more than 15 decimal digits? Python不会用超过15个十进制数字截断float吗? Any examples? 有什么例子吗?

The point is that you get the same output for repr() no matter how many extra digits were originally supplied, 关键是无论最初提供多少个额外的数字,您对于repr()输出都是相同的,

>>> 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 . Python使用dtoa()函数来选择最短的方法来打印出给定的数字,在这种情况下,最短的方法是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, 0.1实际上并不精确:确切的结果是较长的结果,但是dtoa()在打印输出时将数字四舍五入,只要在读回时四舍五入的数字将被四舍五入为原始数字。也就是说,

float(repr(x)) == x

...even though both float() and repr() round their arguments. ...即使float()repr()围绕它们的参数。

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?". 除了Dietrich Epp的出色答案外,该答案还专门解决了“ Python不会用超过15个十进制数字截断float吗?有没有示例?”的问题。

Consider the following Python session: 考虑以下Python会话:

$ 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. 分配给xy的文字仅在一个非常低的有效位上有所不同-您可能需要滚动才能看到它-而xy具有不同的值。 Obviously, that would not be the case if Python truncated based on 15 decimal digits. 显然,如果Python基于15个十进制数字被截断,情况就不会如此。

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. 取而代之的是,它选择最接近十进制文字的IEEE 64位二进制浮点数,并且将四舍五入为带有最低有效小数位为零的位。 I picked y to be exactly half way between two representable numbers, but rounding down. 我选择y恰好介于两个可表示数字之间,但四舍五入。 x is just a tiny bit bigger, so it rounds up. x只是稍大一点,因此将其取整。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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