Perl 数字彼此不相等,但在打印到 STDOUT 时显示相同

标签 perl operators

我正在从两个不同的数据文件中读取数字,并对它们进行一些基本数学运算(将它们加在一起以获得一个文件的总数,并取另一个文件的绝对值)。

当我尝试将它们与 == 运算符进行比较时,它们看起来不相等!但我没有收到任何关于变量如何不是数字或类似内容的错误消息。我想我错过了一些简单的事情,但我一直在用头撞墙。

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

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

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

这是相关的输出:

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!

我唯一能想到的是,它们可能是文件的一些奇怪的编码问题(其中一个文件的名称上有重音符号),但我不知道这会如何影响字符串转换为数字。

我认为通过将数据输出到屏幕,我能够看到发生了什么,但这些数字对我来说看起来完全一样,而且我遇到了多个“匹配”数字的问题,所以我知道程序上有问题。

最佳答案

What Every Programmer Should Know About Floating-Point Arithmetic

#!/usr/bin/perl
use warnings;
use strict;

my %our_payments = (
    one => {total  => '12.1',
            payers => [qw[ x y ]]}
);
my %vendor_payments = (
    last => {x => {total => 9.9 },
             y => {total => 2.2 }}
);
my $last_name = 'last';
my $id = 'one';

my $vendor_total = 0;

print "hash total: ", $our_payments{$id}{'total'}, "\n\n";

my $our_total = abs($our_payments{$id}{'total'});
print "our total: $our_total\n";

foreach my $payer ( @{ $our_payments{$id}{'payers'} } ) {
    print "Adding ", $vendor_payments{$last_name}{$payer}{'total'},
        " to vendor total $vendor_total.\n";

    $vendor_total += $vendor_payments{$last_name}{$payer}{'total'};
}

printf "\nVendor total: %.20f\n", $vendor_total;
printf "Our total: %.20f\n", $our_total;

if ($our_total == $vendor_total) {
    print "Yay! They match!\n";
}
else {
    print "Boo! They don't match!\n";
}

输出:

hash total: 12.1

our total: 12.1
Adding 9.9 to vendor total 0.
Adding 2.2 to vendor total 9.9.

Vendor total: 12.10000000000000142109
Our total: 12.09999999999999964473
Boo! They don't match!

要解决此问题,请不要使用 ==,而应使用类似

if (abs($our_total - $vendor_total) < 1E-10) {

if (sprintf('%.10f', $our_total) eq sprintf('%.10f', $vendor_total)) {

关于Perl 数字彼此不相等,但在打印到 STDOUT 时显示相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77086866/

相关文章:

dynamic - 是否可以使用动态运算符创建动态算术表达式?

java - 从字符串中获取运算符符号

perl 不能使用字符串作为数组引用

java - 如何使用 Java 在 KieServices 中以编程方式注册 Drools 6 自定义运算符

html - 将用户输入从 HTML 页面传递到 Perl 脚本并在网页中显示结果

perl - 如何从 Perl 中的 CSV 文件中提取字段?

c - C 中的运算符优先级 - 返回值

java - 运算符作为 java 中的变量名称与 c 中的 #define 相同

java - MATLAB - 删除二进制文件的元素而不加载整个文件

perl - 如何使用perl处理图论相关问题