我遇到了这个脚本的问题
$total = 0;
$expected_total = 1111;
$i = [85.46,85.46,85.46,85.46,85.46,85.46,85.46,85.46,85.46,85.46,85.46,85.46,85.48];
foreach ($i as $item) { $total += $item; }
if($total != $expected_total) {
echo json_encode([$total,$expected_total]);
}
问题是,在总和的末尾,$ total应该等于$ expected_total。 我想到了不同的数字类型,我打印了两个变量的类型,我是对的,一个是 double ,另一个是整数,所以我转换了整数到 double
$expected_total = 1111.00;
但结果仍然相同。
我能找到的唯一解决方案是比较两个数字的代表性,将它们转换为字符串。
if((string)$total != (string)$expected_total) {
echo json_encode([$total,$expected_total]);
}
但显然这是一种黑客行为。
你有过类似的问题吗?你是怎么解决的?PHP版本:5.5.9 非常感谢
答案 0 :(得分:3)
这不仅是PHP的问题。它是关于浮点数在内存中的表示。浮动数字的精确度有限。 PHP使用IEEE 754。仔细阅读manual page,您就会明白。
您可以在manual代码段中找到如何操作的内容。
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001; //very small number
if(abs($a-$b) < $epsilon) {
echo "true";
}
答案 1 :(得分:0)
PHP Manual中有一个大红色标签,上面写着:
浮点数的精确度有限......
所以永远不要将浮点数结果信任到最后一位数,并且不要直接比较浮点数是否相等。如果需要更高的精度,arbitrary precision math functions和gmp functions可用。
在这种特定情况下,您可以使用bcadd()
添加浮动数字,并使用bccomp()
比较总数。这两个功能都由BC Math扩展程序提供:
foreach ($i as $item) {
$total = bcadd((string) $total, (string) $item, 2);
}
if (bccomp((string) $total, (string) $expected_total, 2) == 0) {
echo json_encode([$total,$expected_total]);
}