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

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

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

Нет-нет, речь не пойдёт о забавных багах типа умножения 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-й степени можно искать только численными методами. Есть ли выход, коллеги?..

Михаил ГУРЧИК,
gor-mike@tut.by

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

Номер: 

14 за 2011 год

Рубрика: 

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

Комментарии

Страницы

Аватар пользователя Инкогнито
>>Забавные злобные, но трусливые, зверюшки. Всё, что пишу я, я могу сказать человеку в лицо.

Слушай, АИ, нах кому тут нужно, что ты можешь сказать в лицо и спину? Скажи по статье свое имхо, если имеется. Или открой новую ветку: Сравнение моральных принципофф менялюбимого со злобноуродливозвериными повадками инкогнитов.

Поддерживаю, что статья -- старческий маразм. Брюзжание, что раньше самолеты не падали, а женщины давали всем без компьютеров. И как минимум четыре безграмотных утверждения, лень искать больше. Самое отпадное -- обоснование перехода с 32 на 64 бита, бугага.

Аватар пользователя Logic
Marmot > Как вы думаете, в 50-е-60-е годы XX века какие компьютеры и с какой точностью рассчитывали траектории спутников?! И ведь летали и приземлялись, куда надо!

Как это куда надо? - Гагарин сел не там, куда надо. - Леонов с Беляевым вообще в тайгу сели (ошибка в тысячи километров) - чуть их волки не съели...

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

Там была ошибка не в ADA, а в том, что Ariane-1 по Ariane-4 стартовали на отлично и тот блок НЕ стали тестировать на Ariane-5, забыв что сама Ariane-5 РЕЗКО отличалась по массе от предыдущих Ariane.

То есть это была ошибка типа - он(блок) хорошо себя показал на предыдущих стартах, не будем его трогать и тестировать на новом старте. - сэкономим типа...

Аватар пользователя Al
Зверушка обиделась, но крыть нечем. ))))
Аватар пользователя mike
>Раньше ... женщины давали всем без компьютеров.

Тянет на афоризм.

>Была ошибка не в ADA...

Я не писал про ошибку в ADA.

Аватар пользователя Инкогнито
>>крыть нечем

коровку кроют

З.Ы. автор мог бы поинтересоваться, скока лет в обед процессоры имеют внутре 64, 80 и 128-битные вычисления..

Аватар пользователя Al
"коровку кроют" - ну вам, как уроженцу отдалённых сельских районов, привычнее это словосочетание именно в таком контексте. Не серчайте, что не поняли мою мысль - читайте книги, посещайте наши форумы, и, возможно, что-то начнёте понимать со временем. ))))

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

Аватар пользователя Инкогнито
>>Не серчайте, что не поняли мою мысль - читайте книги, посещайте наши форумы, и, возможно, что-то начнёте понимать со временем

не фоните :)

>>И поясните пожалуйста, столь нелюбезный, что вы имели в виду, когда просили автора

вы автор?

Аватар пользователя mike
X, есть вопросы? Тогда извинитесь. Иначе ваша критика (даже справедливая) мне ФИ-О-ЛЕ-ТО-ВА.
Аватар пользователя Dmitry
Есть такая, очень давняя, форма подачи материала, как выпукло-акцентированная постановка вопроса, которую надо понимать с известной долей юмора, а не уподобляться крЫтикам, не дочитавшим статью до конца (об чем писал).

Страницы