3
$a = ((0.1 + 0.7) * 10) == (int)((0.1 + 0.7) * 10);

PHP 返回错误。

谁能解释一下,为什么会这样?第一个返回 8,第二个返回 7。

4

7 回答 7

14

引用PHP Manual on Floating Point Precision 中的大红色警告

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

这是因为不可能用有限位数的十进制表示法表示一些分数。例如,1/3十进制形式变为0.3.

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

于 2010-08-18T13:41:00.213 回答
5

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

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

结果:

7.99999999999999911182
于 2010-08-18T13:39:05.190 回答
2

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

编辑

$a = ((0.1 + 0.7) * 10) == 8;
var_dump($a);

echo '<br />';

define('PRECISION', 1.0e-08);

$a = (abs(((0.1 + 0.7) * 10) - 8) < PRECISION);
var_dump($a);
于 2010-08-18T13:38:38.440 回答
1

马克的回应一针见血,但我认为你想要的是圆形 PHP 函数,而不是强制转换:

http://php.net/manual/en/function.round.php

于 2010-08-18T13:42:12.687 回答
1

来自浮点指南(点击查看详细说明):

因为在内部,计算机使用的格式(二进制浮点)根本无法准确表示像 0.1、0.2 或 0.3 这样的数字

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

于 2010-08-18T13:43:46.630 回答
0

因为对浮点数进行操作并不是 100% 准确的,所以在从表达式转换值之前可能是 7.9999...

于 2010-08-18T13:39:44.087 回答
0

您可以通过以下方式进行比较:

$a = round(((0.1 + 0.7) * 10), 1) == (int)round(((0.1 + 0.7) * 10), 1);
于 2010-08-18T14:39:06.893 回答