如何避免在 perl 中产生非常小的计算错误

How to avoid generating a very small computational error in perl

my $a = 243300;
my $b = 3000;
my $c = 81.10;

if (($a - $b * $c) != 0) {
    warn "delta is " . ($a - $b * $c);
} else {
    print "OK\n";
}

结果产生了非常小的差异:

Mac: ~ # perl f.pl
delta is 2.91038304567337e-11 at f.pl line 6.

我可以通过与 0.01 进行比较来解决这个问题,但是如何避免这样的问题以及为什么差异很小?

您可以使用像 Math::BigRat,Math::BigFloat, or Math::Decimal 这样的任意精度数值包,但这会带来显着的性能损失。

use Math::Decimal qw(dec_sub dec_mul);
my ($a,$b,$c,$delta);
$a = 243300;
$b = 3000;
$c = 81.10;
$delta = dec_sub($a, dec_mul($b,$c));
if ($delta != 0) {
    warn "delta [M::D]is $delta\n";
} else {
    print "OK [M::D]\n";
}

use Math::BigRat;
$a = Math::BigRat->new(243300);
$b = Math::BigRat->new(3000);
$c = Math::BigRat->new(81.10);
$delta = $a - $b * $c;
if ($delta != 0) {
    warn "delta [M::BR]is $delta\n";
} else {
    print "OK [M::BR]\n";
}