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

Perl中打印相同的数值用==比较却不相等的问题

问题:浮点数比较看似相等却判定不等

我从两个不同数据文件读取数值,做基础运算:一个取绝对值得到$our_total,另一个求和得到$vendor_total。用==比较时,明明输出显示数值相同,却判定不相等,也没收到类型错误提示。一开始怀疑是文件编码(其中一个文件名带重音符号)影响转数值,但多次测试都出现同样问题,说明是程序层面的错误。

代码片段

my $vendor_total = 0;
            
print "hash total: ", $our_payments{$id}{'total'}, "

";

my $our_total = abs($our_payments{$id}{'total'});
print "our total: $our_total
";
            
foreach my $payer ( @{ $our_payments{$id}{'payers'} } ) {
    print "Adding ", $vendor_payments{$last_name}{$payer}{'total'},
        " to vendor total $vendor_total.
";

    $vendor_total += $vendor_payments{$last_name}{$payer}{'total'};
}
        
print "
Vendor total: $vendor_total
";
print "Our total: $our_total
";
            
if ($our_total == $vendor_total) {
    print "Yay! They match!
";
}
else {
    print "Boo! They don't match!
";
}

运行输出

hash total: -25856.73

our total: 25856.73
Adding 25856.73 to vendor total 0.

Vendor total: 25856.73
Our total: 25856.73
Boo! They don't match!

解决方案

这是浮点数精度误差导致的问题。像25856.73这类十进制小数,无法被二进制浮点数精确表示,存储时会有微小的尾差。比如$our_total是通过abs(-25856.73)得到,而$vendor_total是累加25856.73得到,两者的二进制存储值可能存在极细微的差异,用==直接比较时会被判定为不等。

解决方法:

  • 不要用==直接比较浮点数,而是判断两者的差值是否小于一个极小的阈值(比如1e-6):
    if (abs($our_total - $vendor_total) < 1e-6) {
        print "Yay! They match!\n";
    } else {
        print "Boo! They don't match!\n";
    }
    
  • 如果是处理货币金额这类要求精确的场景,建议用定点数模块(比如Math::BigFloat或Math::Currency),避免浮点数精度损失。

另外,文件名的重音符号不会影响数值转换,这个怀疑可以排除。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:05:12