在 RSpec 中比较浮点数时出现奇怪的行为

5
以下三个测试中第三个测试失败:
  specify { (0.6*2).should eql(1.2) }
  specify { (0.3*3).should eql(0.3*3) }
  specify { (0.3*3).should eql(0.9) } # this one fails

为什么会这样?这是浮点数问题还是ruby或rspec问题?
2个回答

12

从 rspec-2.1 版本开始

specify { (0.6*2).should be_within(0.01).of(1.2) }

在此之前:

specify { (0.6*2).should be_close(1.2, 0.01) }

8

不要将浮点数进行相等比较

问题在于,无论是0.3还是0.9都没有精确的浮点表示形式1,因此当你计算0.3 * 3时,得到的数字非常接近0.9,并且在打印时会四舍五入为0.9,但它并不是0.9。

而你的0.9常量也不是精确的0.9,这两个数字略有不同。

在任何语言中,使用精确相等比较浮点数通常都是错误的。


1. 所有整数最多可以达到约252,具有精确的FP表示形式,但分数由一系列1 / 2n项组成。 大多数十进制字符串分数在基数为2时重复。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接