rspec3中的一些BigDecimal
值可以与aFloat
byeq
进行比较,但有些值不能。
describe "compare BigDecimal with Float" do
it { expect("83.79".to_d).to eq(83.79) } # => fail
it { expect("83.75".to_d).to eq(83.75) } # => succeed
end
为了避免错误,我使用了类似
eq("83.79".to_d)
的表达式。为什么第一次测试失败而第二次测试成功?
最佳答案
永远不要尝试使用浮点值进行任何类型的严格相等测试。您总是必须使用Float
处理不准确的内部表示问题,因此==
和!=
不是非常有用。
考虑一下:
'83.79'.to_d - 83.79
# => #<BigDecimal:7ff33fcea560,'-0.1E-13',9(36)>
'83.75'.to_d - 83.75
# => #<BigDecimal:7ff33fcee688,'0.0',9(27)>
注意,
83.79
的差异不完全为零。如果需要比较浮点值,则始终需要在比较中使用delta;您始终要说:
这些值之间是否有少量的差异?
而不是
这些值相等吗?
在RSPEC术语中:
expect('83.75'.to_d).to be_within(1e-12).of(83.75)
expect('83.79'.to_d).to be_within(1e-12).of(83.79)
并选择delta(
1e-12
在本例中)来匹配您的需求。