На выходных я изложил своему сыну основные тезисы по данной теме. Тот внимательно выслушал мою тираду, немного поразмыслил, затем минут пять "потискал клаву" и выдал такой код
:
Код:
PROCEDURE Do*;
VAR a: SHORTREAL; b: REAL;
BEGIN
Log.Ln;
a := 0.1;
b := a * 1000000; (* b = 100000 *)
b := b - 99999; (* b = 1 *)
b := b * 1000000; (* b = 1000000 *)
b := b - 999999; (*b = 1*)
Log.Real(b);
Log.Ln;
END Do;
Вместо результата 1 эта коротенькая программа выдаёт результат 1491.116119384766
Вспомнилось напоминание
Ильи Ермакова о "погрешностях в хвостах"
Но поражает не это. А то, что погрешность набежала всего за четыре элементарных действия несмотря на то, что операнды в этом примере имеют вполне обычный (в инженерной практике) размер. Скажем, 1000000 может иметь смысл 1МОм или 1 МГц. То есть такие вычисления могут быть сплошь и рядом. Ещё замечу, что до сравнений тут дело не дошло, то есть мы все понимаем, что "зло" проявляется не только при сравнении вещественных чисел.
Очевидный вывод такой: Если SHORTREAL и полезен в чём-то, то только для хранения (больших массивов) результатов вычислений, но не для самих оперативных вычислений. (Думаю, что многие с этим сталкивались, и давно уже пришли к такому выводу).
Тип REAL хоть и не решает проблему в корне, но значительно скрашивает её. Но думаю, что в некоторых задачах не достаточно хорошо скрашивает. Хочу заметить, что диапазон инженерных величин практически не растёт вслед за научно-техническим прогрессом. Поэтому можно надеяться, что 128-битный тип вещественных чисел значительно ослабил бы данную проблему.