Как мне исправить этот код, чтобы 1.1 + 2.2 == 3.3? Что на самом деле здесь происходит, что вызывает такое поведение? Я смутно знаком с задачами округления и математикой с плавающей запятой, но я думал, что это применимо только к делению и умножению и будет видно в выводе.
[me@unixbox1:~/perltests]> cat testmathsimple.pl
#!/usr/bin/perl
use strict;
use warnings;
check_math(1, 2, 3);
check_math(1.1, 2.2, 3.3);
sub check_math {
my $one = shift;
my $two = shift;
my $three = shift;
if ($one + $two == $three) {
print "$one + $two == $three\n";
} else {
print "$one + $two != $three\n";
}
}
[me@unixbox1:~/perltests]> perl testmathsimple.pl
1 + 2 == 3
1.1 + 2.2 != 3.3
Изменить:
Большинство ответов на данный момент соответствуют строкам "это проблема с плавающей запятой, да" и предлагают обходные пути для ее решения. Я уже подозреваю, что в этом проблема. Как мне это продемонстрировать? Как заставить Perl выводить переменные в длинной форме? Сохранение вычисления $ one + $ two в переменной temp и его печать не демонстрируют проблему.
Edit:
Используя технику sprintf, продемонстрированную aschepler, теперь я могу «увидеть» проблему. Кроме того, использование bignum, рекомендованное mscha и rafl, решает проблему несоответствия сравнения. Однако вывод sprintf по-прежнему указывает, что числа не "правильные". Это оставляет небольшое сомнение в этом решении.
Является ли bignum хорошим способом решить эту проблему? Есть ли какие-либо возможные побочные эффекты bignum, на которые мы должны обратить внимание при интеграции его в более крупный существующий, программа?