一些 BigDecimal
值可以通过 Rspec3 中的 eq
与 Float
进行比较,但有些值不能。
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
的差异不完全为零。
如果您需要比较浮点值,您总是需要在比较中使用增量;你总是想说:
Are these values within some small amount from each other?
而不是
Are these values equal?
在 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)
并选择增量(在本例中为 1e-12
)以满足您的要求。
关于ruby - 某些 `BigDecimal` 值与 `Float` 不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35879600/