Далее под катом немного кода на СИ и одна проблема. Если у вас есть немного свободного времени и вы программист, то я буду очень рад помощи. ( Помочь... )
Обычно так бывает из-за того, что в программе есть неинициализированные переменные, в которых на разных машинах оказывается разный мусор. Тем не менее, the IEEE standard does not guarantee that the same program will deliver identical results on all conforming systems, так что, если вы работаете с хаосом, где это и должно происходить, то, может, вам как раз удалось сконструировать именно тот пример, где результаты должных быть совсем другие. Есть возможность запостить программу целиком?
Код программы довольно большой. Там много функций, и чтобы понять принцип их работы нужно иметь представление об одной математической теории. И, да, возможно есть пара неинициализированных переменных, но я ими не пользуюсь.
Так я уже делал. Компилятор говорит, что в трёх функциях есть неиспользованные переменные, но при решении этой задачи я не обращаюсь к этим функциям вообще.
Вроде как аппаратной реализации тригонометрических функций в современных процессорах для персоналок нет.
Немного работал с Фортраном. Там возможны сюрпризы с ключами компилятора при оптимизации под конкретный процессор, есть ключи при которых скорость выполнения арифметических операций увеличивается за счет нарушения стандарта IEEE.
Точность вещественных арифметических вычислений задается в коде. Наиболее распространенными являются одинарная точность (float, 32 двоичных разряда) и двойная точность (double, 64 разряда). Есть еще увеличенная (80 разрядов) и половинная (16). С заданием типов переменных, аргументов, констант из-за этого приходится быть аккуратным. Вроде здесь немного описано, касательно тригонометрических функций http://msdn.microsoft.com/ru-ru/library/wkbss70y.aspx
Есть вопрос как именно в коде или в конкретном компиляторе определяется константа M_PI.
Ну хм, не знаю, во-первых, не так уж точно этот синус вычисляется на FPP, во-вторых, есть четыре режима округления; в-третьих, вас что, устраивают неустойчивые решения? А смысл? Вы тогда зависите от ошибок округления, это не хаос, а обычные ошибки.
Я хочу сказать, что вы экспериментируете, похоже, не с математикой, а со случайным кодом. Не очень понимаю, что в этом может быть интересного, и какая в этом может быть сермяжная правда.
Например, 3.14/10.0 уже достаточно, чтобы внести в вычисления произвольную чушь. Потому что не делится на двоичных машинах.
По-моему очевидно, что ошибки меня не устраивают - иначе не писал бы этот пост. И мне тоже кажется, что проблема с кодом, а не с исследуемой моделью. Но также вполне естественно, что при анализе происходящего и поиске ошибок, я принимаю во внимание свойства исследуемой системы. Естественно, что хочется получить работающий код, который на разных компьютерах даёт одинаковый результат
( ... )
При вычислении 3.14/10.0*ds.t возникают ошибки округления (число 3.14 непредставимо в виде конечной двоичной дроби), и результат "прыгает" в зависимости от того, в какую сторону будет округляться итог. А Вы в результате изучаете особенности не отображения, а архитектуры компьютера. :)
Собственно, это предположение можно легко проверить. Я соорудил программку, которая считает первое отображение (в котором никаких синусов нет), но с разной точностью (двойной и четверной). Разница результатов начинается, естественно, с 10^{-16}, но уже за несколько десятков итераций доходит до 10^0.
Так что Вам просто повезло - первое отображение все используемые компьютеры считают одинаково (и, по-видимому, одинаково неверно). Во втором же случае появляются какие-то мелкие различия, которые приводят к разным результатам.
FPP, последний раз, когда я это исследовал, давал всего 32 бита мантиссы на тригонометрических функциях. Четыре режима округления (ими можно управлять) - это к плюс бесконечности, к минус бесконечности, к нулю, к ближайшему чётному.
Вы делите на 10, т.е. на 2 и на 5. На 2 делить ошибки нет, а на 5 деление получается неточное, потому что это не степерь двойки, дробь бесконечная. и там остаток отбрасывается.
Да, в целях сохранения душевного здоровья - лучше считать что в разных "системах" - разные синусы. Под "системами" я понимаю связку не просто процессор, а связку процессор+математическая библиотека+компилятор.
Это можно победить, но лучше считать что они разные.
Ну да, динамические ситесмы они такие, но как бы и не страшно - погрешность измерительных приборов гораздо больше, чем погрешность double. Есть ещё более страшная проблема - погрешность модели. Если вы эмулируете физический процесс, то вы не учли ветер, изменение гравитации от высоты, или ещё что-нибудь.
У меня тут больше математическая задача. Если в аргументе синуса стоит M_PI/30.0*ds.t, то я получаю различные результаты. Если же заменить M_PI/30.0 на приблизительное 0.10471975511966, то всё встаёт на свои места. На сколько я понимаю корень зла кроется в ошибки округления при делении на 30.0.
Я согласен с аргументом про общий случай, но данный случай очень частный. Если я правильно понял автора, он сводится к разному поведению деления на двух разных ieee-совместимых машинах. Я бы безусловно ожидал побитового совпадения. А сейчас бы, соответственно, распечатывал двоичное представление М_PI / 30.0 в обоих случаях.
Comments 24
Reply
Код программы довольно большой. Там много функций, и чтобы понять принцип их работы нужно иметь представление об одной математической теории. И, да, возможно есть пара неинициализированных переменных, но я ими не пользуюсь.
И спасибо за ссылку.
Reply
Reply
Reply
Немного работал с Фортраном. Там возможны сюрпризы с ключами компилятора при оптимизации под конкретный процессор, есть ключи при которых скорость выполнения арифметических операций увеличивается за счет нарушения стандарта IEEE.
Reply
Reply
Есть вопрос как именно в коде или в конкретном компиляторе определяется константа M_PI.
Reply
Я хочу сказать, что вы экспериментируете, похоже, не с математикой, а со случайным кодом. Не очень понимаю, что в этом может быть интересного, и какая в этом может быть сермяжная правда.
Например, 3.14/10.0 уже достаточно, чтобы внести в вычисления произвольную чушь.
Потому что не делится на двоичных машинах.
Чего вы хотите добиться-то?
Reply
Reply
Собственно, это предположение можно легко проверить. Я соорудил программку, которая считает первое отображение (в котором никаких синусов нет), но с разной точностью (двойной и четверной). Разница результатов начинается, естественно, с 10^{-16}, но уже за несколько десятков итераций доходит до 10^0.
Так что Вам просто повезло - первое отображение все используемые компьютеры считают одинаково (и, по-видимому, одинаково неверно). Во втором же случае появляются какие-то мелкие различия, которые приводят к разным результатам.
Reply
Четыре режима округления (ими можно управлять) - это к плюс бесконечности, к минус бесконечности, к нулю, к ближайшему чётному.
Вы делите на 10, т.е. на 2 и на 5. На 2 делить ошибки нет, а на 5 деление получается неточное, потому что это не степерь двойки, дробь бесконечная. и там остаток отбрасывается.
Reply
Это можно победить, но лучше считать что они разные.
Ну да, динамические ситесмы они такие, но как бы и не страшно - погрешность измерительных приборов гораздо больше, чем погрешность double. Есть ещё более страшная проблема - погрешность модели. Если вы эмулируете физический процесс, то вы не учли ветер, изменение гравитации от высоты, или ещё что-нибудь.
Reply
Как это можно победить?
Reply
Нужно вдумываться в конкретную задачу.
Вычислениями на компьютере можно проверить, что два выражения очень близки, но невозможно доказать что два выражения в точности равны.
Например, с точки зрения double ( cos(0.00000001) - 1 ) в точности равно нулю, но это не значит что 0.00000001 -- неподвижная точка для (cos(x)-1+x)
Reply
Reply
Leave a comment