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

Laravel8/PHP8下sum求和等于100却触发>100判断原因求解

问题原因

这是符合IEEE 754标准的二进制浮点数固有的精度误差问题,PHP的浮点数运算默认遵循该标准:

  • 你手动计算的十进制数值总和为100,但7.4、1.3755、10.4这类十进制小数无法被二进制浮点数精确表示,存储时本身就存在极微小的误差,累加后实际存储的数值可能是100.0000000000001这类非常接近100、但实际大于100的数值
  • 直接做> 100的比较时会触发判断条件,而dump输出时PHP默认会将这类极小误差的浮点值四舍五入为100显示,所以会出现打印结果为100、但判断100 > 100返回true的异常表现
  • 强制转float类型并不能解决问题,因为精度损失在数值存储阶段就已经产生了
解决方案

你可以根据业务精度需求选择以下任意一种方案:

  1. 引入可接受的误差阈值(epsilon)做比较
    设置一个远小于业务允许最小精度的阈值,判断总和与100的差值是否超过该阈值:
$measuresByTS->each(function ($measures) {
    $sum = $measures['keys']->sum('key');
    $allowError = 0.00001; // 可根据业务需要调整,示例为允许万分之一的误差
    if ($sum - 100 > $allowError) {
        dump("sum is superior to 100 : ". $sum);
    }
});
  1. 放大为整数运算后比较
    将所有数值放大为整数后再累加比较,完全规避浮点数精度问题,示例中你使用的数值最多保留4位小数,可放大10000倍:
$measuresByTS->each(function ($measures) {
    $sumInt = $measures['keys']->sum(fn($item) => (int)round($item['key'] * 10000));
    if ($sumInt > 1000000) {
        $sum = $measures['keys']->sum('key');
        dump("sum is superior to 100 : ". $sum);
    }
});
  1. 使用BC Math高精度扩展运算
    如果需要更高的精度控制,可以使用PHP官方的BC Math扩展做高精度运算:
$measuresByTS->each(function ($measures) {
    $sum = '0';
    foreach ($measures['keys'] as $item) {
        $sum = bcadd($sum, (string)$item['key'], 4); // 4为保留的小数位数,可按需调整
    }
    if (bccomp($sum, '100', 4) > 0) {
        dump("sum is superior to 100 : ". $sum);
    }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 12:15:04