如何避免在 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";
}
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";
}