OSDev http://osdev.su/ |
|
Беседа о создании математической библиотеки для ЯП http://osdev.su/viewtopic.php?f=18&t=1057 |
Страница 2 из 5 |
Автор: | Freeman [ 23 мар 2015, 13:34 ] |
Заголовок сообщения: | Re: Беседа о создании математической библиотеки для ЯП |
Yoda писал(а): Интересная бодяга, почему компилятор GCC настойчиво считает не как остальные. Он считает как Delphi. В обычном Delphi нельзя воспроизвести результат с умолчательным контрольным словом сопроцессора для процесса Windows, только с хакерским модулем System от проекта KOL, как у меня. Поэтому стандартным для Delphi является результат с контрольным словом $1372, который как раз равен 1.2875059979e+26. |
Автор: | Zealint [ 23 мар 2015, 15:00 ] |
Заголовок сообщения: | Re: Беседа о создании математической библиотеки для ЯП |
В целом-то понятно, почему результат будет близок к 10^26, ведь double обеспечивает около 15 значащих цифр, а в результате некоторых действий их становится уже 14. От есть 40-14=26. Таким образом, 10^26 - это относительная погрешность для чисел порядка 10^40 и тех арифметических действий, что мы делаем. Собственно, ответ в примере Yoda действительно будет 0 с погрешностью около 10^26 Прикол в том, что разные компиляторы могут по разному генерировать код вычислений. Поменяв порядок действий, мы можем получить совершенно разные ответы. Просто все это совершенно неочевидно для рядовых программистов. В моём примере специально были маленькие числа, чтобы показать, что они не играют никакой роли. Но в разных программах я упорно вижу попытки работать с плавающей арифметикой без понимания её принципов: там мешают всё подряд, сравнивают с одной и той же абсолютной погрешностью не зависимо от размера чисел и ловят непонятные баги. Видимо, мне придётся на эту тему сделать какой-то основательный обзор... А то как работать с математической библиотекой без понимания тонкостей плавающей арифметики. Цитата: В данной формулировке получается, что VAX лишён этой проблемы, верно? Как я понял, там арифметика с фиксированной точкой, которая позволяет использовать абсолютную погрешность на все случаи. Эта арифметика более очевидна и если я, скажем, хочу прибавить к 10^20 число 1 (один) миллиард раз, я получу то, что должен был получить, а не то же самое 10^20. |
Автор: | Freeman [ 23 мар 2015, 15:41 ] |
Заголовок сообщения: | Re: Беседа о создании математической библиотеки для ЯП |
Я ночью полез было смотреть инструкции SSE, чтобы написать этот кусок на ассемблере, но в этот раз бессонница была не такой жестокой. |
Автор: | Zealint [ 23 мар 2015, 20:48 ] |
Заголовок сообщения: | Re: Беседа о создании математической библиотеки для ЯП |
А чём поможет SSE? От того, что удастся сразу два double за раз умножить вряд ли результат сильно поменяется. |
Автор: | Freeman [ 23 мар 2015, 21:08 ] |
Заголовок сообщения: | Re: Беседа о создании математической библиотеки для ЯП |
Zealint писал(а): Таким образом, 10^26 - это относительная погрешность для чисел порядка 10^40 и тех арифметических действий, что мы делаем. Собственно, ответ в примере Yoda действительно будет 0 с погрешностью около 10^26 Чёрт возьми! Тогда результат 0,0, полученный мной для 80-битного типа Extended, верен для общего случая, а установка слова сопроцессора нужна Delphi как раз для повышенной точности. GCC как, умеет работать с 80-битным типом? А вы сами себе противоречите, сначала говоря, что погрешность рядом не лежала с объявленной для double, а теперь признавая обратное. Zealint писал(а): А чём поможет SSE? От того, что удастся сразу два double за раз умножить вряд ли результат сильно поменяется. А в каком-то из SSE разве не было 128-битных плавающих значений? Я до этого пока не дошел. Знаю только, что 80-битные в x64 выпилили. |
Автор: | Zealint [ 23 мар 2015, 21:27 ] |
Заголовок сообщения: | Re: Беседа о создании математической библиотеки для ЯП |
Freeman писал(а): А вы сами себе противоречите, сначала говоря, что погрешность рядом не лежала с объявленной для double, а теперь признавая обратное. Не совсем так. Я сказал Цитата: что вычисления даже близко не подходят к границам применения double То есть мы не вышли за пределы применения типа данных (1.7e308), но точность в привычном для человека смысле потеряли. Согласитесь, трудно считать число 10^26 почти нулём : ) И похожая неочевидность порождают очень много ошибок при работе с плавающей арифметикой, говорят, даже ракеты падают из-за этого. Вот представьте, что Вы бы попались на это в реальном проекте: вычитаете два одинаковых числа, а у вас получается сто миллионов миллиардов миллиардов! Начнёте отлаживать, напьётесь зелёного чая, кто-то другой на Вашем месте может и вовсе в обморок упасть от ужаса. И это ещё полбеды. Беда приходит, когда от этого умирают (и о таких случаях тоже ходят слухи) - когда ошибка становится результатом аварии со смертельным исходом. Вот я о чём - о непредсказуемости и неочевидности плавающей арифметики. И я ещё не начал даже разговора о более суровых примерах, когда мы вроде бы маленькие числа считаем, а в конце получается фигня. Я поищу, может, эти примеры, где-то их видел раньше. Freeman писал(а): А в каком-то из SSE разве не было 128-битных плавающих значений? Насколько я знаю, нет. Смысл SSE (Streaming SIMD Extensions) как раз в том, чтобы те же операции делать в потоковом режиме: сразу много за один раз. Например, можно перемножить сразу 4 float за раз, или 2 double. Это ускоряет, например, задачу перемножения матриц, когда нужно брать длинные суммы произведений, но это не повышает точность расчётов. |
Автор: | Zealint [ 23 мар 2015, 21:57 ] |
Заголовок сообщения: | Re: Беседа о создании математической библиотеки для ЯП |
Вот, кстати, более интересные ошибки можно поискать здесь. Ищите там сразу §9. Проблемы компьютерных вычислений, вызванные использованием стандарта IEEE754. Десятый параграф тоже можно прочитать, но я бы критично его оценил. Разумеется, все эти вещи - это ошибки человека. Но извольте, трудно управлять неконтролируемой погрешностью. Особенно когда о ней ничего не знаешь. Бывает, читаешь код, написанный профессионалом, а там написано Код: if ( abs ( a - b ) < EPS ) { ... } Причём EPS указана в виде константы, заданной заранее на все случаи. Например, часто берут 1e-8. А когда выясняется, что 10^26 тоже может быть нулём... в общем, понимаете? Люди в целом плохо знают плавающую арифметику, раз даже профессионалы совершают очевидные ошибки. Но я вас уверяю, даже если бы они знали всё это, вероятность ошибок была бы всё равно в десятки раз выше, чем при работе с целыми числами. Я лично считаю плавающую арифметику плохим инструментом. |
Автор: | SII [ 24 мар 2015, 08:45 ] |
Заголовок сообщения: | Re: Беседа о создании математической библиотеки для ЯП |
Zealint писал(а): Я лично считаю плавающую арифметику плохим инструментом. Который, однако, весьма неплохо работает в основной массе задач, требующих вещественной арифметики. |
Автор: | Yoda [ 24 мар 2015, 13:22 ] |
Заголовок сообщения: | Re: Беседа о создании математической библиотеки для ЯП |
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 писал(а): Я лично считаю плавающую арифметику плохим инструментом. Уж какой есть. За невозможностью разработать лучший для ряда задач приходится пользоваться этим. Важно понимать, что можно от неё ожидать, а что - нет, и не применять её там, где вреда больше, чем пользы. |
Автор: | Freeman [ 24 мар 2015, 23:34 ] |
Заголовок сообщения: | Re: Беседа о создании математической библиотеки для ЯП |
Yoda писал(а): Опять же, я не вижу способа решить эту проблему полностью, она носит фундаментальный характер. В любом представлении с фиксированным количеством значащих разрядов мы либо ограничиваем диапазон, либо ограничиваем точность, но не можем получить и то и другое сразу. По одной из ссылок про страшилки IEEE754 есть статья про какую-то аппроксиметику, которую я смотрел только по диагонали. Преподносится автором как серебряная пуля, само собой. Если кто-то сможет проанализировать и сказать, годная идея или нет, буду только рад. |
Страница 2 из 5 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |