ре пишут программное обеспечение для
Программисты, кото- ре пишут программное обеспечение для численных расчетов, должны хоро-шо разбираться в методах оценки и контроля этих ошибок. Вот три грубые ошибки, которые могут произойти:
Операнд сложения или вычитания может исчезнуть, если он относительно мал по сравнению с другим операндом. При десятичной арифметике с пятью цифрами:
0.1234 х 103 + 0.1234 х 10-4 = 0.1234 х 103
Маловероятно, что преподаватель средней школы учил вас, что х + у = х для ненулевого у, но именно это здесь и произошло!
Умножение ошибки — это большая абсолютная ошибка, которая может появиться при использовании арифметики с плавающей точкой, даже если относительная ошибка мала. Обычно это является результатом умножения деления. Рассмотрим вычисление х • х:
0.1234 х103 • 0.1234 х 103 = 0.1522 х 105
и предположим теперь, что при вычислении х произошла ошибка на единицу младшего разряда, что соответствует абсолютной ошибке 0.1:
0.1235 х 103 • 0.1235 х 103 = 0.1525 х 105
Абсолютная ошибка теперь равна 30, что в 300 раз превышает ошибку перед умножением.
Наиболее грубая ошибка — полная потеря значимости, вызванная вычитанием почти равных чисел:
C |
float f2 = 0.12346;
B математике f2 -f1 = 0.00004, что, конечно, вполне представимо как четырехразрядное число с плавающей точкой: 0.4000 х 10-4. Однако программа, вы-числяющая f2 - f 1 в четырехразрядном представлении с плавающей точкой, даст ответ:
0.1235 10°-0.1234x10° = 0.1000 х 10-3
что даже приблизительно не является приемлемым ответом.
Потеря значимости встречается намного чаще, чем можно было бы предположить, потому что проверка на равенство обычно реализуется вычитанием и последующим сравнением с нулем. Следующий условный оператор, таким образом, совершенно недопустим:
C |
f2=…;
if (f1 ==f2)...