Можно ли предсказать, когда математика Perl в десятичной / плавающей запятой будет неправильной?
В одном отношении я понимаю, что плавающие в Perl неточные двоичные представления, что иногда приводит к неверным вычислениям в Perl. Чего я не понимаю, так это того, почему иногда эти ответы дают точные ответы, а иногда нет. Можно ли предсказать, когда математические вычисления в Perl дадут неправильный ответ (т. Е. Неточный ответ)?
Например, в приведенном ниже коде математика Perl неверна 1 раз, когда вычитание равно "16.12 - 15.13", неверна 2 раза, когда проблема равна "26.12 - 25.13", и неверная 20 раз, когда проблема равна "36.12 - 35.13"., Кроме того, по какой-то причине во всех вышеупомянутых тестовых случаях результат нашей проблемы вычитания (то есть $subtraction_problem) начинается как неправильный, но, как правило, становится более корректным, чем больше мы добавляем или вычитаем из него (с $ х). Это не имеет смысла, почему чем больше мы добавляем или вычитаем из нашей арифметической задачи, тем больше вероятность того, что значение будет правильным (то есть точным)?
my $subtraction_problem = 16.12 - 15.13;
my $perl_math_failures = 0;
for (my $x = -25; $x< 25; $x++){
my $result = $subtraction_problem +$x;
print "$result\n";
$perl_math_failures++ if length $result > 6;
}
print "There were $perl_math_failures perl math failures!\n";
1 ответ
Ничто из этого не относится к Perl. Смотри Гольдберг:
Ошибка округления
Сжатие бесконечного числа действительных чисел в конечное число бит требует приблизительного представления. Хотя целых чисел бесконечно много, в большинстве программ результат целочисленных вычислений может храниться в 32 битах. Напротив, при любом фиксированном количестве битов большинство вычислений с действительными числами будут давать величины, которые не могут быть точно представлены с использованием такого количества битов. Поэтому результат вычисления с плавающей точкой часто должен быть округлен, чтобы соответствовать его конечному представлению. Эта ошибка округления является характерной особенностью вычисления с плавающей точкой. Раздел Относительная ошибка и Ulps описывает, как она измеряется.
Поскольку большинство вычислений с плавающей точкой в любом случае имеют ошибку округления, имеет ли значение, если базовые арифметические операции вносят чуть больше ошибки округления, чем необходимо? Этот вопрос является основной темой в этом разделе. В разделе "Защитные цифры" обсуждаются защитные цифры, способ уменьшения ошибки при вычитании двух соседних чисел. Защитные цифры были признаны IBM достаточно важными, так как в 1968 году она добавила защитную цифру в формат двойной точности в архитектуре System/360 (одинарная точность уже имела защитную цифру) и модернизировала все существующие машины в полевых условиях. Два примера приведены для иллюстрации полезности защитных цифр.
Стандарт IEEE идет дальше, чем просто требование использования защитной цифры. Он дает алгоритм сложения, вычитания, умножения, деления и квадратного корня и требует, чтобы реализации давали тот же результат, что и этот алгоритм. Таким образом, когда программа перемещается с одного компьютера на другой, результаты основных операций будут одинаковыми во всех битах, если обе машины будут поддерживать стандарт IEEE. Это значительно упрощает портирование программ. Другое использование этой точной спецификации дано в Точно Округленных Операциях.