为什么 python print() 打印一个舍入值而不是不可表示的浮点数的精确值
值 0.1
不能表示为 64 位浮点数。 确切值大致等于 0.10000000000000000555
https://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/
您可以用这个简单的代码突出显示此行为:
timestep = 0.1
iterations = 1_000_000
total = 0
for _ in range(iterations):
total += timestep
print(total - timestep * iterations) # output is not zero but 1.3328826753422618e-06
我完全理解为什么 0.1
不能表示为 float 64 的精确值,但我不明白的是为什么当我执行 print(0.1)
时,它会输出0.1
而不是作为 float 64 的基础值。
当然,基础值在以 10 为基数的系统上有更多的数字,因此应该涉及一些舍入,但我正在寻找所有的规范值以及如何控制它。
我遇到了一些应用程序在数据库中存储数据的问题:
- python 应用程序(使用
str(0.1)
)将显示0.1
- 另一个数据库客户端 UI 将显示
0.10000000000000000555< /code>,这会让最终用户感到困惑
P-S:我对其他值有其他问题
问候,
The value 0.1
is not representable as a 64 bits floats.
The exact value is roughly equals to 0.10000000000000000555
https://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/
You can highlight this behavior with this simple code:
timestep = 0.1
iterations = 1_000_000
total = 0
for _ in range(iterations):
total += timestep
print(total - timestep * iterations) # output is not zero but 1.3328826753422618e-06
I totally understand why 0.1
is not representable as an exact value as a float 64, but what I don't get is why when I do print(0.1)
, it outputs 0.1
and not the underlying value as a float 64.
Of course, the underlying value has many more digits on a base 10 system so there should be some rounding involved, but I am looking for the specification for all values and how to control that.
I had the issue with some application storing data in database:
- the python app (using
str(0.1)
) would show0.1
- another database client UI would show
0.10000000000000000555
, which would throw off the end user
P-S: I had other issues with other values
Regards,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,你是对的,浮点数(单浮点数、双浮点数等)具有精确的值。
对于 64 位 IEEE-754 双精度,最接近 0.1 的可表示值将恰好是
0.1000000000000000055511151231257827021181583404541015625
,如您所见,相当长。但可表示的浮点值都具有有限数量的十进制数字,因为基数 (2) 是 10 的某个幂的除数。对于像 python 这样的 REPL 语言,必须具有以下属性:
结果是
为了获得这些属性,有几种可能性:
Python 和许多其他语言选择了第三种解决方案,因为当用户输入
0.1
时打印0.100000000000000001
被认为很烦人。人类用户通常选择较短的表示形式,而打印的表示形式供人类消费。越短越好。不好的特性是,它可能会给人一种错误的印象,即这些浮点值存储的是精确的十进制值,例如 1/10。现在这里和许多地方都在传播这种知识。
First, you are right, floats (single, double, whatever) have an exact value.
For 64 bits IEEE-754 double, the nearest representable value to 0.1 would be exactly
0.1000000000000000055511151231257827021181583404541015625
, quite long as you can see. But representable floating point values all have a finite number of decimal digits, because the base (2) is a divisor of some power of 10.For a REPL language like python, it is essential to have this property:
A consequence is that
For obtaining those properties, there are several possbilities:
Python, and many other languages have chosen the 3rd solution, because it is considered annoying to print
0.10000000000000001
when user have entered0.1
. Human users generally choose the shorter representation and printed representation is for human consumption. The shorter, the better.The bad property is that it could give the false impression that those floating point values are storing exact decimal values like 1/10. That's a knowledge that is evangelized here and in many places now.