$a = ((0.1 + 0.7) * 10) == (int)((0.1 + 0.7) * 10);
PHP 返回错误。
谁能解释一下,为什么会这样?第一个返回 8,第二个返回 7。
$a = ((0.1 + 0.7) * 10) == (int)((0.1 + 0.7) * 10);
PHP 返回错误。
谁能解释一下,为什么会这样?第一个返回 8,第二个返回 7。
引用PHP Manual on Floating Point Precision 中的大红色警告:
通常,简单的十进制分数喜欢
0.1
或0.7
不能转换为它们的内部二进制对应物,而不会造成小的精度损失。这可能会导致令人困惑的结果:例如,floor((0.1+0.7)*10)
通常会返回7
而不是预期的8
,因为内部表示将类似于7.9
.这是因为不可能用有限位数的十进制表示法表示一些分数。例如,
1/3
十进制形式变为0.3
.所以永远不要相信浮点数的结果是最后一位,也不要比较浮点数是否相等。如果需要更高的精度,可以使用任意精度的数学函数和gmp函数。
浮点运算并不精确。而不是 8.0,你可以得到 7.999... 当转换为整数时,它会被截断为 7。
echo number_format((0.1 + 0.7) * 10, 20);
结果:
7.99999999999999911182
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);
马克的回应一针见血,但我认为你想要的是圆形 PHP 函数,而不是强制转换:
来自浮点指南(点击查看详细说明):
因为在内部,计算机使用的格式(二进制浮点)根本无法准确表示像 0.1、0.2 或 0.3 这样的数字。
当代码被编译或解释时,你的“0.1”已经被四舍五入到该格式中最接近的数字,这会在计算发生之前导致一个小的舍入误差。
因为对浮点数进行操作并不是 100% 准确的,所以在从表达式转换值之前可能是 7.9999...
您可以通过以下方式进行比较:
$a = round(((0.1 + 0.7) * 10), 1) == (int)round(((0.1 + 0.7) * 10), 1);