PHP floor()的怪异行为


PHP floor() weird behaviour

当对乘法运算的结果进行floor运算时,我得到的结果与对正常数进行floor计算时不同。这种行为是意料之中的事吗?如果是,为什么?

$val1 = 29;
$val2 = 0.29*100;
echo floor($val1); // prints 29
echo floor($val2); // prints 28

这是PHP中浮点精度的结果,在您的示例中:

gettype($val1);返回integer

gettype($val2);返回double

结合php.net上的警告:

此外,有理数可以精确地表示为以10为底的浮点数字,如0.1或0.7,没有精确表示为以2为基数的浮点数,即内部使用,无论尾数大小。因此,他们如果没有精度损失小。这可能会导致令人困惑的结果:例如,floor((0.1+0.7)*10)通常返回7,而不是预期为8,因为内部表示将类似7.999999999999999 1118….

取自http://php.net/manual/en/language.types.float.php

我们可以看到为什么你的楼层从28.9999999999等降到28,而不是29到29的整数。

这是PHP怪异精度的一部分。这是正常的,取决于机器。

浮点数字的精度有限。尽管这取决于系统,PHP通常使用IEEE 754双精度格式,由于四舍五入将产生最大相对误差数量级为1.11e-16。非初等算术运算可以给出较大的误差,当然,还必须考虑误差的传播当几个操作被复合时。

此外,有理数可以精确地表示为以10为底的浮点数字,如0.1或0.7,没有精确表示为以2为基数的浮点数,即内部使用,无论尾数大小。因此,他们如果没有精度损失小。这可能会导致令人困惑的结果:例如,floor((0.1+0.7)*10)通常返回7,而不是预期为8,因为内部表示将类似7.999999999999999 1118….

因此,永远不要相信浮点数的结果是最后一位,也不要直接比较浮点数是否相等。如果更高精度是必要的,任意精度的数学函数和gmp功能可用。

http://techiedan.com/2013/10/11/php-floor-function-float-value/