我正在从两个不同的数据文件中读取数字,并对它们进行一些基本数学运算(将它们加在一起以获得一个文件的总数,并取另一个文件的绝对值)。
当我尝试将它们与 == 运算符进行比较时,它们看起来不相等!但我没有收到任何关于变量如何不是数字或类似内容的错误消息。我想我错过了一些简单的事情,但我一直在用头撞墙。
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/