Точность в Эрланге - PullRequest
       4

Точность в Эрланге

6 голосов
/ 05 октября 2011

Следующий код дает мне 5.999999999999998 в результате, но правильный ответ - 6.

Alpha = math:acos((4*4 + 5*5 - 3*3) / (2*4*5))
Area = 1/2 * 4 * 5 * math:sin(Alpha)

Можно ли получить 6?

Ответы [ 2 ]

24 голосов
/ 05 октября 2011

Вы столкнулись с проблемой, настолько распространенной, что у нее есть собственный веб-сайт, Что должен знать каждый программист об арифметике с плавающей точкой . Проблема заключается в том, что арифметика с плавающей точкой работает практически во всех процессорах на рынке, которые поддерживают арифметику FP; это не характерно для Erlang.

Если обычная арифметика с плавающей запятой не дает необходимой вам точности или точности, вы можете использовать арифметическую библиотеку произвольной точности вместо встроенной арифметики. Возможно, наиболее известной такой библиотекой является GMP , но вам придется заключить ее в NIFs , чтобы использовать ее из Erlang.

Существует по крайней мере одна альтернатива на чистом Эрланге , но у меня нет с этим опыта, поэтому я не могу лично это одобрить.

8 голосов
/ 05 октября 2011

Расчет выполняется с использованием стандартной арифметики с плавающей запятой на вашем оборудовании.Иногда появляются ошибки округления.

Вам действительно нужны 15 цифр точности?

Чтобы получить более "точное" значение, существует несколько вариантов:

> round(Area). % Will round to integer
6

илиВы можете округлить с некоторой точностью

round(Area * 10000000) / 10000000.
6.0

Если цель состоит в том, чтобы напечатать значение, то печать с выводом по умолчанию для чисел с плавающей запятой даст вам меньшую точность.

io:format("~f~n", [Area]).
6.000000
ok

или с определеннойточность

io:format("~.14f~n", [Area]).
6.00000000000000
ok

HTH

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...