You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中相似数组求和结果为何出现判断差异?

PHP浮点数求和的精度问题(Laravel 8 + PHP 8环境)

在Laravel 8、PHP 8环境下开发时遇到一个特殊情况:两个数组仅元素顺序和微小数值不同,理论上求和结果都应该是100。用array_sum计算后,dump显示两者结果都是100.0,但条件判断时,其中一个数组的求和结果能判定等于100和100.0,另一个却判定不等。原本以为这和PHP_FLOAT_EPSILON无关,实际恰恰是浮点数精度导致的问题。

相关代码如下:

$c = [
    23.3,
    33.4,
    43.3,
];
$d = [
    43.3,
    23.4,
    33.3,
];

$ccc = array_sum($c);
$ddd = array_sum($d);

dump($ccc);  // output: 100.0
dump($ddd);  // output: 100.0

if ($ccc != 100) {
    dump('$ccc is not equal to 100');
} else {
    dump('$ccc is equal to 100');  // 实际输出这行
}
if ($ccc != 100.0) {
    dump('$ccc is not equal to 100.0');
} else {
    dump('$ccc is equal to 100.0');  // 实际输出这行
}

if ($ddd != 100) {
    dump('$ddd is not equal to 100');  // 实际输出这行
} else {
    dump('$ddd is equal to 100');
}
if ($ddd != 100.0) {
    dump('$ddd is not equal to 100.0');  // 实际输出这行
} else {
    dump('$ddd is equal to 100.0');
}

问题原因

本质是浮点数的二进制存储精度限制:像23.3、33.4这类十进制小数,无法被精确转换成二进制浮点数,存储时本身就带有微小误差。当不同顺序的浮点数累加时,这些误差会被累积放大,最终导致$ddd的实际值和100.0存在极小的差异(比如可能是100.00000000000003或者99.99999999999997),而dump输出时做了四舍五入显示,所以看起来都是100.0,但实际比较时就能测出差异。

解决方案

  1. 使用高精度数学扩展:比如PHP的bcmath扩展,通过精确的十进制计算避免浮点数误差,示例代码:
function bc_array_sum($array, $scale = 2) {
    $sum = '0';
    foreach ($array as $num) {
        $sum = bcadd($sum, (string)$num, $scale);
    }
    return $sum;
}

$ccc = bc_array_sum($c);
$ddd = bc_array_sum($d);

// 此时比较字符串形式的数值即可
if ($ddd == '100.00') {
    // 相等逻辑
}
  1. 允许误差范围的比较:如果必须使用浮点数,比较时用PHP_FLOAT_EPSILON判断差值是否在可接受的精度范围内:
if (abs($ddd - 100.0) < PHP_FLOAT_EPSILON) {
    dump('$ddd is equal to 100.0');
} else {
    dump('$ddd is not equal to 100.0');
}

内容的提问来源于stack exchange,提问作者enaeim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 05:43:16