【发布时间】:2011-05-13 06:37:51
【问题描述】:
echo (int) ( (0.1+0.7) * 10 );
为什么上面的输出是 7?我了解 PHP 如何向 0 舍入,但 (0.1+0.7) * 10 不是评估为浮点数然后转换为整数吗?
谢谢!
【问题讨论】:
-
我认为这发生在任何语言中,这是因为浮点数在内部处理的方式
标签: php floating-point integer
echo (int) ( (0.1+0.7) * 10 );
为什么上面的输出是 7?我了解 PHP 如何向 0 舍入,但 (0.1+0.7) * 10 不是评估为浮点数然后转换为整数吗?
谢谢!
【问题讨论】:
标签: php floating-point integer
我没有安装php,但是在python中:
$ python
>>> 0.1+0.7
0.79999999999999993
>>>
并非所有以 10 为底的数字都可以在以 2 为底的系统中精确表示。查看维基百科文章:
部分二进制分数。特别是这一行:
Fraction Decimal Binary Fractional Approx.
1/10 0.1 0.000110011... 1/16+1/32+1/256...
1/10 不能以 2 为底的有限方式表示。因此,0.1 + 0.7 不能以 2 为底精确计算。
永远不要假设浮点计算是精确的,它迟早会咬你。
【讨论】:
参见手册:
http://php.net/manual/en/language.types.float.php
简单的小数是典型的 不能像 0.1 或 0.7 这样的分数 转换成它们的内部二进制文件 同行没有小的损失 精确。这可能会导致混乱 结果:例如, floor((0.1+0.7)*10) 通常会 返回 7 而不是预期的 8, 因为内部表示将 大概是 7.9。
【讨论】:
1/10 不能用有限数量的二进制数字表示,就像 1/3 不能用有限数量的 base-10 数字表示一样。因此,您实际上是在将 0.09999999999999... 和 0.69999999999999... 相加 - 总和是几乎 8,但不完全。
【讨论】:
其他答案解释了为什么会发生这种情况。这应该可以得到你想要的:
echo (int) round( (0.1+0.7) * 10 );
在将浮点数转换为 int 之前,只需 四舍五入。
【讨论】: