2010-08-18 127 views
3
$a = ((0.1 + 0.7) * 10) == (int)((0.1 + 0.7) * 10); 

PHP返回false。在PHP中舍入

有人可以解释我,为什么会发生? 首先返回图8,第二7.

+2

:http://docs.sun.com/source/806-3568/ncg_goldberg.html – webbiedave 2010-08-18 13:53:17

+0

另请参阅我的文章http://www.exploringbinary.com/when-floats-dont-behave-like-floats/(特别参见程序2)。 (基本上只是在下面的答案中描述的现象的更多细节,尽管在不同的上下文中)。 – 2010-08-18 18:57:04

回答

5

浮点算术并不精确。而不是8.0正好你可以得到7.999 ...当被转换为整数时被截断为7。

echo number_format((0.1 + 0.7) * 10, 20); 

结果:

7.99999999999999911182 
+2

''var_dump((0.1 + 0.7)* 10);'将'float(8)'四舍五入'输出无助于此。 – 2010-08-18 13:46:01

0

因为浮点数操作不是100%准确,propably从表达铸造前值是一样的东西7.9999 ...

14

引述big fat red warning in the PHP Manual on Floating Point Precision

典型的是简单的小数部分如0.10.7不能转换成其内部的二进制对应,而不会有小的精度损失。这可能会导致令人困惑的结果:例如,floor((0.1+0.7)*10)通常会返回7而不是预期的8,因为内部表示将类似于7.9

这是由于这样一个事实,即不可能用有限数字的数字表示一些十进制符号的分数。例如,十进制形式的1/3变成0.3

所以不要将浮点数结果信任到最后一位数字,也绝不会比较浮点数是否相等。如果需要更高的精度,则可以使用the arbitrary precision math functionsgmp功能。

+0

特别是,只能用“p/q”形式表示的小数,其中q是2的整数次幂,p是任意整数,可以用有限数量的比特精确表示。 – Artefacto 2010-08-18 15:02:20

1

The Flaoting-Point Guide(点击查看详细解释):

由于内部计算机使用 格式(二进制浮点数),因此 无法准确表示数字 ,如0.1,0.2或0.3,,全部为

当代码被编译或解释 ,你的“0.1”是已经 四舍五入至在于 格式最接近的数字,这导致一个小 舍入误差的 计算发生甚至之前。

0

你可以做的比较是这样的:如果你想钻研长的答案

$a = round(((0.1 + 0.7) * 10), 1) == (int)round(((0.1 + 0.7) * 10), 1);