2010-04-01 2 views
3

Является ли класс BigDecimal сломанным? Похоже, следующие должны никогда, никогда не произойдет: Обратите внимание, что a.to_f = a.to_s.to_fBigDecimal to_s не соответствует to_f

класс A.class => BigDecimal

a.to_f => +18658,1072928!

a.to_s => "10865,81072928"

b.class => BigDecimal

b.to_f => 10000.0

b.to_s => "10000,0"

(а - Ь) .to_f => +865,81072928

a.to_f - b.to_f => 8658.1072928

Любые идеи относительно того, что может быть неправильно? Мы используем ruby ​​1.8.7p72 на наших серверах и 1.8.7p173 на наших локальных машинах.

+0

Как и где вы задаете свои переменные a и b. ps: нет проблем с рубином 1.8.6 – fl00r

ответ

0

Как docs говорят:

to_f:

Возвращает новый объект Float, имеющий примерно ту же величину, что и числа BigDecimal. Применяются нормальные пределы точности и встроенные ошибки бинарной арифметики Float.

Это означает, что Float в рубин ведет себя так же, как поплавок везде: http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

Не каждое число представимо поплавком. В таких случаях число округляется.

+0

a.to_f => 18658.1072928 a.to_s => "10865.81072928" Я не думаю, что мы можем обвинить разницу почти в 8000 при ошибке округления ... –

+0

Вы правильно. Я также тестировал его на своей локальной машине (я тоже запускаю 1.8.7p173), и результаты разные: >> a = BigDecimal.new ('10865.81072928') => # >> a.to_s => "0.186581072928E5" >> a.to_f => +18658,1072928 не знаю, почему ... –

Смежные вопросы