Zealint писал(а):
Прикол в том, что разные компиляторы могут по разному генерировать код вычислений. Поменяв порядок действий, мы можем получить совершенно разные ответы.
Именно по этой причине на компиляторы обычно накладываются ограничения в работе с плавающей арифметикой. Так, они не имеют права оптимизировать (без специальных на то указаний) плавающую арифметику, меняя порядок операций.
Zealint писал(а):
Видимо, мне придётся на эту тему сделать какой-то основательный обзор...
Вот тот обзор на хабре (упомянутый мной ранее) мне показался вполне обзорным.
Zealint писал(а):
Yoda писал(а):
В данной формулировке получается, что VAX лишён этой проблемы, верно?
Как я понял, там арифметика с фиксированной точкой, которая позволяет использовать абсолютную погрешность на все случаи. Эта арифметика более очевидна и если я, скажем, хочу прибавить к 10^20 число 1 (
один) миллиард раз, я получу то, что должен был получить, а не то же самое 10^20.
С чего бы вдруг? По части представления чисел ваксы в основном похожи на IEEE:
http://nssdc.gsfc.nasa.gov/nssdc/format ... gPoint.htmНикакой фиксированной точки там нет. Также там нет и ряда других концепций, таких как специальные и денормализованные числа, поэтому ваксы подвержены ряду проблем: "околонулевая яма", неправомерная выдача правдоподобного результата, -0 != +0 и т.п. Собс-но, прелесть ваксов заключалась, пожалуй, только в 128-битной арифметике при наличии специального процессорного модуля расширения.
Опять же, я не вижу способа решить эту проблему полностью, она носит фундаментальный характер. В любом представлении с фиксированным количеством значащих разрядов мы либо ограничиваем диапазон, либо ограничиваем точность, но не можем получить и то и другое сразу. Число 10^40 требует ceil(40/log(2))-40 = 93 двоичных разряда мантиссы для хранения без потери, что сильно превышает возможности 80-битных чисел с плавающей точкой В ЛЮБОМ представлении, а ещё немного и превысит даже возможности расширенных ваксов. Главная мысль - плавающая арифметика имеет неразрешимые внутренние проблемы (не важно, какое представление мы выбрали), специалисту их необходимо постоянно держать в голове и учитывать при написании программ.
Zealint писал(а):
Бывает, читаешь код, написанный профессионалом, а там написано
Код:
if ( abs ( a - b ) < EPS ) { ... }
Да-да, ужасная, КАТАСТРОФИЧЕСКАЯ ошибка.
Zealint писал(а):
Я лично считаю плавающую арифметику плохим инструментом.
Уж какой есть. За невозможностью разработать лучший для ряда задач приходится пользоваться этим. Важно понимать, что можно от неё ожидать, а что - нет, и не применять её там, где вреда больше, чем пользы.