?

Log in

Точность вычислений - числа с плавающей точкой. Экспонента считается неверно? - Жить не можем без проблем! [entries|archive|friends|userinfo]
Жить не можем без проблем!

[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Точность вычислений - числа с плавающей точкой. Экспонента считается неверно? [Jan. 23rd, 2011|01:29 am]
Жить не можем без проблем!

ru_lisp

[kit1980ukr]
Нашел баг в библиотеке alexandria: субфакториалы (http://en.wikipedia.org/wiki/Subfactorial) читаются неверно, начиная с 11.

Формула там верная - (floor (/ (+ 1 (factorial n)) (exp 1)))

Но, например, для 11 получается (/ 39916801 2.7182817) => 1.4684571e7, после округления получаем 14684571 вместо 14684570.

Ладно, точность (exp 1) маленькая, пишем явно
(/ 39916801 2.7182818284590452353602874713526624977572470936999595749669), но все равно получаем 1.4684571e7

Python, например, считает точнее:
>>> 39916801 / 2.7182818284590452353602874713526624977572470936999595749669
14684570.445231671

Как это побороть (считать с большей точностью)?

Компилятор - SBCL

P.S. Обнаружил, что экспонента считается неверно.
CL-USER> (exp 1)
2.7182817

А более точное значение - 2.7182818284590452353602874713526624977572470936999595749669..., т.е.должно округляться до 2.7182818

P.P.S
Уже подсказали, что надо писать (exp 1d0), тогда проблемы с точностью решаются.
В общем-то, это и будет фиксом для alexandria:subfactorial, но только для чисел до 18 включительно. Другая формула нужна.
linkReply

Comments:
[User Picture]From: love5an
2011-01-23 05:32 am (UTC)
ну совершенно ясно что все это от ограничений точности в числах с плавающей точкой.
Формула основана на e, и на округлении.
Так как e - число трансцендентное, рациональной дробью его представить нельзя, можно только до определенной точности. float лисповые в точности ограничены машинными флоатами, то есть максимум - long-float, который суть long double 80-битный, например(в clisp так; в sbcl есть только double-float). Произвольная точность задается через рациональную дробь, но опять же, e - только приближением. Погрешность, соответственно, все так же будет, просто после определенного числа.

Но вроде бы есть формула и без e, если верить википедии
(Reply) (Thread)
From: (Anonymous)
2012-06-15 07:03 am (UTC)
а для ln((1+x)/(1-x)) , по какой формуле посчитать и как? спасибо
(Reply) (Thread)