在Ruby on Rails中比较两个几乎相同的BigDecimal数字

时间:2015-02-13 05:42:31

标签: ruby precision equality bigdecimal

我遇到了一个我真正想了解的问题。我正在使用assert_equal来比较两个应该相同的BigDecimal数字。它们实际上只是一小部分,见下文:

-#<BigDecimal:7f4b40e8de78,'0.4021666666 6666666666 666666667E2',36(45)>
+#<BigDecimal:7f4b40e85db8,'0.4021666666 6666666666 6666668E2',36(63)>

我使用assert_in_delta以免测试用例失败。所以我得到了一个合理的解决方法。我确实想知道是否有可能让它平等:

assert_equal (241.30.to_d/6), model.division_function

模型division_function完全相同。它将值241.3的BigDecimal除以数组的长度,即6

精确度似乎有微小差异。 我想知道那可能来自哪里? 有没有办法可以更准确地控制精度?

修改 我正在使用Mongoid。值得注意的是,Mongoid提供BigDecimal作为字段类型,但它存储为字符串。但是,我不认为这是问题所在。我相信这是一件Ruby事情。

修改 我进一步了解了一个示例,该示例暗示它是一个Ruby问题并且与Rails没有直接关系。请参阅以下内容:

irb(main):041:0* amount1 = BigDecimal("241.3")
=> #<BigDecimal:7f49bcb03558,'0.2413E3',18(18)>
irb(main):042:0> amount2 = BigDecimal("1800")
=> #<BigDecimal:7f49bcaf3400,'0.18E4',9(18)>
irb(main):043:0> rate = amount1 / amount2
=> #<BigDecimal:7f49bcae8398,'0.1340555555 5555555555 5555556E0',27(45)>
irb(main):044:0> rate * amount2 #should return amount1 = 241.3, but it does not :-(
=> #<BigDecimal:7f49bcad6a30,'0.2413000000 0000000000 00000008E3',36(45)>
irb(main):045:0> 

1 个答案:

答案 0 :(得分:2)

我向Ruby核心团队报告了bug。但是,这不是错误,因为您可以在拒绝响应中看到。

BigDecimal虽然提供任意精度,但不能精确地表示1/3之类的数字。因此,在某些算术中,您可能会遇到不精确的情况。

您可以在Ruby中使用Rational来获取确切的数字。如果您希望保持结果准确,请在做算术时谨慎行事。

相关问题