2

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

4

2 回答 2

11

这都是关于float。请参阅PHP:浮点数

警告 - 浮点精度

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

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

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

补充阅读:

于 2012-07-20T05:33:52.833 回答
1

哈雷的回答很棒。

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

例如,通常习惯于在投射时四舍五入以到达最近的位置

(int) (x + 0.5)

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

于 2012-07-20T05:42:07.573 回答