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

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

15.04.2011 — Новости Hi-Tech |  
Размер текста:
A
A
A

Источник материала:

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

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

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

 
 
Чтобы разместить новость на сайте или в блоге скопируйте код:
На вашем ресурсе это будет выглядеть так
Если кто-то думает, что его домашний компьютер имеет дело с бесконечным множеством чисел - он жестоко ошибается...
 
 
 

РЕКЛАМА

Архив (Новости Hi-Tech)

РЕКЛАМА


Яндекс.Метрика