为什么PHP本身会将(int)((0.1 + 0.7)* 10)的结果转换为7而不是8?

时间:2012-07-20 05:26:59

标签: php floating-point rounding

为什么地球上的PHP会将(int) ((0.1+0.7)*10)的结果转换为7而不是8?我知道结果将是(float) 8,当它被转换为(int)时,结果将为7?为什么会这样?

2 个答案:

答案 0 :(得分:11)

关于float。见PHP: Floating point numbers

  

警告 - 浮点精度

     

浮点数的精度有限。虽然它取决于系统,但PHP通常使用IEEE 754双精度格式,由于舍入的顺序为1.11e-16,因此会产生最大的相对误差。非基本算术运算可能会产生更大的误差,当然,当复合多个运算时,必须考虑误差传播。

     

此外,基本10中的浮点数精确表示的有理数,如0.1或0.7,没有精确表示为基数2中的浮点数,无论尾数的大小如何,它都在内部使用。因此,它们不能在没有很小精度损失的情况下转换为它们的内部二进制对应物。这可能导致令人困惑的结果:例如,floor((0.1 + 0.7)* 10)通常会返回7而不是预期的8,因为内部表示将类似于7.9999999999999991118 ....

     

所以永远不要将浮点数结果信任到最后一位数,并且不要直接比较浮点数是否相等。如果需要更高的精度,可以使用任意精度数学函数和gmp函数。

补充阅读:

答案 1 :(得分:1)

哈利的答案很棒。

您需要的其他信息是,无论它们与下一个数字有多接近,转换为int始终会截断小数。所以(int)7.999999999999将是7。

通常习惯于在投射时进行舍入以达到最近,例如

(int) (x + 0.5)

有许多函数可以处理浮点和舍入,截断等。您需要阅读它们并选择适合您需要的函数。