php中$a = 0.3; $b = 1-0.7; var_dump($a == $b);为false $c = 0.7; $d = 1-0.3; var_dump($c == $d);

为true 这是为什么呢
2024-12-15 23:52:33
推荐回答(2个)
回答1:

浮点数的精度有限。尽管取决于系统,PHP 通常使用 IEEE 754 双精度格式,则由于取整而导致的最大相对误差为
1.11e-16。非基本数学运算可能会给出更大误差,并且要考虑到进行复合运算时的误差传递。

此外,以十进制能够精确表示的有理数如 0.1 或
0.7,无论有多少尾数都不能被内部所使用的二进制精确表示,因此不能在不丢失一点点精度的情况下转换为二进制的格式。这就会造成混乱的结果:例如,floor((0.1+0.7)*10)
通常会返回 7 而不是预期中的 8,因为该结果内部的表示其实是类似
7.9999999999999991118...。

所以永远不要相信浮点数结果精确到了最后一位,也永远不要比较两个浮点数是否相等。如果确实需要更高的精度,应该使用任意精度数学函数或者 gmp 函数。

回答2:

0.3、0.7这样的小数在机器内要换算为二进制,换算成为的二进制有可能是个无限的循环小数,这样就会有误差,不能精确表示。

0.3的二进制格式是:
0.010011001100110011001100110011001100110011001100110011

0.7的二进制格式是:
0.1011001100110011001100110011001100110011001100110011

可以看出位数都是很长的,如果超过机器的精度,就会四舍五入。另外1-0.3、1-0.7的计算过程中也会出现相应的误差,所以浮点数的相等判断没有实际意义,一般是判断两个数的差的绝对值比一个规定的精度小,就算相等。例如:
if (abs(x-y)<0.0000001) echo '相等';