Рассмотрим следующую спецификацию:
require 'bigdecimal'
def total_percent(amounts)
percent_changes = amounts.each_cons(2).map { |a|
(a[1] - a[0]) / a[0] * BigDecimal.new('100.0')
}
(percent_changes.map { |pc| BigDecimal.new('1') + pc / BigDecimal.new('100') }.inject(BigDecimal.new('1'), :*) - BigDecimal.new('1')) * BigDecimal.new('100')
end
describe 'total_percent' do
specify {
values = [10000.0, 10100.0, 10200.0, 10000.0].map { |v|
BigDecimal.new(v.to_s)
}
total_percent(values).class.should == BigDecimal
total_percent(values).should == BigDecimal.new('0.0')
}
end
Метод total_percent
вычисляет общую разницу списка значений в процентах.Пожалуйста, не обращайте внимания на сам алгоритм (тот же результат может быть достигнут путем просмотра только первого и последнего значений).
Спецификация не выполняется, поскольку результат вычисления не равен 0.0
.Вопрос в том, где теряется точность.
Редактировать: Использование JRuby 1.6.5 на OS X 10.7.2.