См. Что должен знать каждый компьютерщик об арифметике с плавающей точкой .
Ничто из этого не относится к конкретному Perl: существует бесконечно большое количество действительных чисел, и, очевидно, все они не могут быть представлены с использованием только конечного числа битов.
Специальное "решение""использовать зависит от вашей конкретной проблемы.Вы пытаетесь отслеживать денежные суммы?Если это так, используйте числа произвольной точности (используйте больше памяти и больше ЦП, чтобы получить более точные результаты), предоставленные bignum .Вы делаете числовой анализ?Затем определитесь с точностью, которую вы хотите использовать, и используйте sprintf
(как показано ниже) и eq
для сравнения.
Вы всегда можете использовать:
use strict; use warnings;
check_summation(1, $_) for [1, 2, 3], [1.1, 2.2, 3.3];
sub check_summation {
my $precision = shift;
my ($x, $y, $expected) = @{ $_[0] };
my $result = $x + $y;
for my $n ( $x, $y, $expected, $result) {
$n = sprintf('%.*f', $precision, $n);
}
if ( $expected eq $result ) {
printf "%s + %s = %s\n", $x, $y, $expected;
}
else {
printf "%s + %s != %s\n", $x, $y, $expected;
}
return;
}
Выход:
1.0 + 2.0 = 3.0
1.1 + 2.2 = 3.3