5

我有一个关联数组,其值是浮点数,应该是概率。因此,我总结它们并要求结果实际上是 1。

$total = array_sum($array);
echo '$total = '.$total."\n";
if ($total == 1) {
    die("total is 1");
} else {
    die("total is not 1");
}

这神秘地输出:

$total = 1
total is not 1

做一个var_dump($total)yield float(1),甚至$total == (float)1返回 false。

这是怎么回事?

4

3 回答 3

3

浮点值本质上是不精确的,并且由于它们的存储方式和舍入误差而很少彼此相等。您应该通过查看这两个值是否“足够接近”来比较浮点数。也就是说,将两个值之间的差值的绝对值与非常小的误差范围(通常称为“epsilon”)进行比较。

一种这样的实现可能是:

if (abs($total - 1) < 0.000000001)
    die("total is 1");
} else {
    die("total is not 1");
}

请注意,只有您的应用程序的要求才能真正确定安全误差范围是多少,以及在什么时候应该对数字进行四舍五入以进行显示。


例如,如果您正在处理货币值并且需要精确的精度,更好的解决方案是完全放弃浮点运算。在这种情况下,一种选择是使用整数类型并将数字存储为美分,仅在最后一分钟除以向用户显示数字(或者甚至不除,而是在字符串中注入小数点)。

于 2013-09-06T17:23:29.833 回答
2

php(和其他语言)中的浮点数并不精确,因此(float)1实际上可能是1.00000000000000123113.99999999999999823477

有关更多信息,请参阅答案PHP - 浮点数精度

于 2013-09-06T17:21:22.463 回答
1

投射到 int 做

if ((int)$total == 1)

它会起作用:)

编辑:甚至更好

$total = (int)array_sum($array);
于 2013-09-06T17:23:24.407 回答