2010-01-13 3 views
8

При написании теста со значением, которое представляется в виде BigDecimal, я столкнулся с чем-то странным и решил в него разобраться. Короче говоря, «0.00009» при округлении до двух знаков после запятой возвращается как 0,01 вместо 0,00. В самом деле. Вот мой сценарий/консоль захвата:Ruby BigDecimal Round: Это ошибка?

>> bp = BigDecimal('0.09') 
=> #<BigDecimal:210fe08,'0.9E-1',4(8)> 
>> bp.round(2,BigDecimal::ROUND_HALF_DOWN).to_f 
=> 0.09 
>> bp = BigDecimal('0.009') 
=> #<BigDecimal:210bcf4,'0.9E-2',4(8)> 
>> bp.round(2,BigDecimal::ROUND_HALF_DOWN).to_f 
=> 0.01 
>> bp = BigDecimal('0.0009') 
=> #<BigDecimal:2107a8c,'0.9E-3',4(12)> 
>> bp.round(2,BigDecimal::ROUND_HALF_DOWN).to_f 
=> 0.0 
>> bp = BigDecimal('0.00009') 
=> #<BigDecimal:2103428,'0.9E-4',4(12)> 
>> bp.round(2,BigDecimal::ROUND_HALF_DOWN).to_f 
=> 0.01 
>> bp = BigDecimal('0.000009') 
=> #<BigDecimal:20ff0f8,'0.9E-5',4(12)> 
>> bp.round(2,BigDecimal::ROUND_HALF_DOWN).to_f 
=> 0.0 

О, и я получаю те же результаты, если я использую режим по умолчанию, например, так:

>> bd = BigDecimal('0.00009') 
=> #<BigDecimal:2152ed8,'0.9E-4',4(12)> 
>> bd.round(2).to_f 
=> 0.01 

Вот мои варианты:

ruby 1.8.6 (2008-03-03 patchlevel 114) [i686-darwin9.2.2] 
Rails 2.3.4 

Кто-нибудь видел что-нибудь подобное?

+0

Я не могу воспроизвести его в своей среде 1.8.7 (ruby 1.8.7 (2009-06-12 patchlevel 174) [x86_64-linux]) – bryantsai

ответ

6

Нет, никогда не видел этого раньше, и это определенно похоже на ошибку. 0.00009, округленное до двух знаков после запятой, обязательно должно быть 0.00.

ROUND_HALF_DOWN не должен изменять поведение, поскольку вы не имеете значения средней величины.

This link имеет более подробную информацию.

Кажется, что ошибка в 1,8 уровнях была исправлена ​​в 1.9. Это немного странно, потому что это только влияет на число с четным числом нулей до первой ненулевой цифры и только если эта цифра равна 5 или больше.

Это, как представляется, точно Ваша проблема на основе предоставленных данных.

+0

Да, похоже, это действительно моя проблема! Спасибо за слежку! –

0

Я думаю, что это тоже ошибка, но о чем мне интересно, это .to_f, чтобы отобразить результат. С BigDecimal вы должны использовать .to_s ('F'), так как я предполагаю, что у вас есть причина использовать BigDecimal вместо Floats.

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