考虑以下规范:
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
。问题是它在哪里失去了精度。
编辑:在 OS X 10.7.2 上使用 JRuby 1.6.5。