rspec3中的一些BigDecimal值可以与aFloatbyeq进行比较,但有些值不能。

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在本例中)来匹配您的需求。

10-02 03:56