Проклятие компьютеров

- Чем отличается инженер от программиста?

- Инженер знает, откуда берутся числа.

Нет-нет, речь не пойдёт о забавных багах типа умножения 77,1 на 850 с помощью Excel 2007. На форумах "Вестей" мы это обсуждали. Всё гораздо более серьёзно. Если кто-то думает, что его домашний компьютер имеет дело с бесконечным множеством чисел - он жестоко ошибается. Множество чисел в вашем компьютере вполне конечно, но каждое такое число отображает бесконечное подмножество вещественных чисел. Проделаем простой эксперимент. Напишем следующий код. Я выбрал любимый Си, но убеждён, что там, где используются числа с плавающей запятой, от языка программирования мало что зависит.

#include<stdio.h>
int main()
{
 float x,x1;
 x = (12.0/11.0-1.0)*11.0; /*(1)*/
 x1 = (12.0/11.0-1.0)*11.0-1.0; /*(2)*/
 printf("x=%e\nx1=%e\n", x,x1);
 return(0);
}

Вы, конечно, полагаете, что результатами будут 1.0 и 0.0? Не спешите. Запускаем на выполнение (у меня компилятор GNU GCC на 32 двоичных разряда), получаем: x=1.000000e+00 - что, собственно, и ожидалось; однако обнаруживаем, что x1=-8.881784e-16, а вовсе не 0.000000e+00. Замена типов переменных на тип double неожиданно не спасает. Ясно, что если в цикле многократно суммировать результаты вычислений по выражениям, подобным выражению (2), то в итоге получится далеко не 0. А если после этого в программе встретится ветвление по сравнению, то вероятность, что программа пойдёт "не в ту степь", становится вполне ощутимой. Хорошо, если программа считает нечто теоретическое, а если это вычисления в реальном времени, например, корректировка курса? Тогда рано или поздно в поведении оборудования что-то пойдёт не так. Ошибки по этой причине случаются, но программисты о таких случаях предпочитают не распространяться, потому что такие ошибки то и дело приводят к печальным последствиям. Судите сами.

25 февраля 1991 г. батарее "Пэтриот" в Дхаране (Саудовская Аравия) не удалось перехватить приближающуюся иракскую ракету "Скад", которая попала в казарму, уничтожив сразу 28 солдат армии США. Расследование показало, что причиной явилось накопление погрешностей вычисления в одном из алгоритмов, рассчитывающих траекторию полёта ракеты противника.

4 июня 1996 г. через 40 секунд после старта французская ракета Ariane-5 (без экипажа) самоликвидировалась. Расследование выявило, что причина крылась в преобразовании типа double в тип float c потерей первоначального значения переменной. Не помог и хвалёный язык Ада, на котором писались исходники.

Вы легко найдёте в Интернете немало описаний подобных аварий, вызванных конечностью множества чисел, с которыми оперирует компьютер. Причиной этой конечности является сложившаяся практика. В технике используются числа, как правило, имеющие пять-шесть значащих цифр. Правда, у метрологов значность числа достигает десятка, но всё равно остаётся конечной. Поэтому из чисто экономических соображений разработчики решили не только ограничить разрядность процессоров, что вполне разумно и понятно, но и ограничить множество вещественных чисел, разработав стандарт IEEE754, дабы программисты не особо себя утруждали. IEEE-числа - это столбы на оси вещественных чисел и между ними ещё ну о-очень много места. В самом деле, если 2^10 ~ 10^3, то для практической точности хватает 32 двоичных разряда процессора с некоторой ошибкой округления. Понятно, что чем меньше эта ошибка, тем меньше вероятность аварий из-за "нечеловеческого" компьютерного фактора и тем большим становится безопасное количество циклов, в которых возможно накопление ошибок. По-моему, переход на 64-разрядные процессоры обусловила именно эта причина (если не принимать во внимание маркетинг), а вовсе не желание тотально повысить быстродействие.

Однако думается, что было бы неверным считать, что увеличение разрядности процессора компьютера или расширение форматов чисел с плавающей запятой (см., например, en.wikipedia.org/wiki/Quadruple_precision) - панацея от вычислительных казусов. В настоящее время для практических целей используются измерительные приборы, имеющие точность не выше класса 0.1%. По-видимому, физики раньше, чем компьютерщики, осознали, насколько коварны погрешности, вызываемые ошибками округления, и насколько важно их минимизировать. Вот ещё пример.

Пусть вы располагаете рулеткой с ценой деления 1 мм. Ясно, что как бы вы старательно не измеряли длину-ширину-толщину доски, погрешность измерения всё равно останется. Фишка, однако, в цели измерения. Если необходимо вычислить кубатуру доски, то ошибка, полученная в результате вычисления этой кубатуры, будет вполне приемлемой. Если же вам путём вычислений требуется предсказать число кувырков доски при падении с высоты значительно большей, чем длина доски, то почти гарантированно вы получите неверный результат, так как в процессе решения обязательно произойдёт накопление погрешностей первоначальных данных. Причём, как бы вы не увеличивали разрядность процессора компьютера, нового качества в своих предсказаниях не достигнете, поскольку ошибка содержится в начальных условиях, а компьютер лишь размножает и накапливает эту ошибку. И суперкомпьютер, между прочим, тут не спасает. Поэтому физики, осознав, что числа с запятой, как фиксированной, так и плавающей, непригодны для основополагающих эталонов, перешли на целые числа с нулевой погрешностью округления, напрочь отбросив запятую как чуждый им класс. Мало кто задумывается, что с 1983 г. скорость света в системе СИ больше не является измеряемой величиной, а Парижский метр отнюдь не эталон длины. Эталоном является секунда как интервал времени, равный 9192631770 периодам излучения между сверхтонкими уровнями Cs133 при 0 К в отсутствии внешних полей. Метр - это длина пути, проходимая светом в вакууме за 1/299792458 секунды. Скорость света в вакууме в СИ является константой в самом прямом смысле этого слова: 299792458 м/с, причём ТОЧНО!

Впрочем, ещё раньше, чем физики, непригодность плавающей запятой как стандарта поняли банкиры при внедрении компьютеров в своё дело, заставив программистов создать тип CURRENCY, который по существу представляет собой целое число с искусственной запятой, отделяющей для удобства последние два десятичных знака. А чтобы не забивать себе голову переводами из десятичной системы счисления в двоичную и наоборот, решили каждый десятичный разряд представлять в так называемом BCD-формате. В этом формате число 0x123456 равно десятичному 1234,56.

А что же инженерные компьютеры? Как это раньше без них человечество обходилось? Дело в том, что в докомпьютерной вычислительной технологии на основе приближенных исходных данных накопления ошибок НЕ БЫЛО, потому что всё, что можно, традиционно вычислялось по символьным формулам. И дома стояли, и пароходы плавали, и поезда ходили. А сейчас в угаре всеобщей компьютеризации то самолеты падают, то крыши рушатся. Видимо, слишком привыкли инженеры доверять компьютерам и численным методам нахождения решений.

Если слишком довериться суперкомпьютерам, то рано или поздно может случиться мировая катастрофа, так как датчики на входах портов суперкомпьютеров всегда имеют ограниченную точность. Поэтому увеличение точности всякого рода прогнозов, благодаря суперкомпьютерам, - выдумки досужих журналистов или же тривиальное выбивание денег для строительства очередного монстра. А может, лучше просто запретить использовать суперкомпьютеры для ответственных задач и снова вернуться к формулам? Увы, это невозможно. Техника усложнилась неимоверно. И даже школьники знают, что корни полинома выше 5-й степени можно искать только численными методами. Есть ли выход, коллеги?..

Михаил ГУРЧИК,
[email protected]

Версия для печатиВерсия для печати

Номер: 

14 за 2011 год

Рубрика: 

Размышлизмы
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!

Комментарии

Страницы

Аватар пользователя Marmot
Статья начинается интересно, но вот дальше...

Михаил, ну зачем же вы зря людей пугаете? Вычислительные погрешности и проблема их накопления известны уже очень давно - тут вы не открыли Америку! И теория, и способы расчета погрешностей тоже давно существуют. И там, где нужна особо высокая точность расчетов, используются числа соответствующей разрядности. Но писать о каком-то "машинном апокалипсисе" из-за накопления погрешностей - значит, сеять панику на пустом месте. Как вы думаете, в 50-е-60-е годы XX века какие компьютеры и с какой точностью рассчитывали траектории спутников?! И ведь летали и приземлялись, куда надо!

На самом деле, катастрофы обычно происходят из-за ошибок в программах, а не из-за погрешностей. Иначе не было бы смысла в моделировании сложных процессов, предсказании погоды и многом другом, где в цикле обсчитываются миллиарды чисел!..

Аватар пользователя Marmot
Ах, да! Забыл про последний абзац: ну, это вообще финиш!

> А может, лучше просто запретить использовать суперкомпьютеры для ответственных задач и снова вернуться к формулам?

Нет, лучше вообще запретить использовать компьютеры и вернуться в пещеры: так безопаснее!

Михаил, вы в курсе, что в докомпьютерную эпоху в расчетах использовали логарифмическую линейку (точность - 3 знака) и таблицы Брадиса (4 знака)?!

Мне жаль "Компьютерные вести": печатают такие некомпетентные статьи!..

Аватар пользователя Инкогнито
Автор статьи - жертва новой системы образования.
Аватар пользователя другой Инкогнито
Не согласен. Образование тут ни при чем. Автор статьи - жертва старческого маразма. Возраст дает о себе знать. Плюс повседневная работа с Линуксом, непосильная для такого пожилого человека...
Аватар пользователя Dmitry
_Нет, лучше вообще запретить использовать компьютеры и вернуться в пещеры: так безопаснее!_

Это называется "НЕ дочитал", т.к. следующая же авторская реплика - "Увы, это невозможно".

Аватар пользователя Al
Умиляет меня поведение иксов. "Не кусну так хоть плюну!" Забавные злобные, но трусливые, зверюшки. Всё, что пишу я, я могу сказать человеку в лицо. А эти - только на форумах смелы. Любая критика должна быть конструктивной, иначе это просто п...ж.
Аватар пользователя mike
>катастрофы обычно происходят из-за ошибок в программах, а не из-за погрешностей.

Ага. Вот недомыслие -- это ошибка или нет?

>в докомпьютерную эпоху в расчетах использовали логарифмическую линейку... Знаю. Сам считал. По формулам.

>Автор - жертва старческого маразма. ... плюс повседневная работа с Линуксом, непосильная для такого пожилого...

Занял ваше место на полосе?

Аватар пользователя Savely
Принципиально Майк, конечно, прав.

Только он увлекся "примитивными" примерами и фактами из жизни, и некоторые бросились критиковать примеры. Хотя Майк сам же сказал по ходу, что обычно в жизни нам хватает точности компа при правильном применении численных методов.

P.S. Кстати, старенький досовский Borland С дает 3.2xxxxE-19. А майкрософтовский CL вроде от VC60 - совпадает с Майком.

Аватар пользователя Savely
А выход - усложнять софт. Никто ж не мешает считать с любой точностью и на 32битном процессоре. Долго только...
Аватар пользователя Инкогнито
Сейсмическая катастрофа в Японии была заблаговременно предсказана сотрудниками Российской академии наук.

http://elibrary.ru/item.asp?id=15628544

Отличительная особенность этих результатов состоит в использовании огромных массивов данных регистрации микросейсмических колебаний на территории Японии и современных методов их математической обработки.

Страницы