奇怪的舍入问题

使用小数和浮点数发生了一些非常奇怪的事情,我无法理解为什么或在哪里(ruby / rails / postgresql)。

给定带有小数列的购买表 – 总计

p1 = Purchase.where(total: 5.99).first_or_create p2 = Purchase.where(total: 5.99).first_or_create [p1.id, p2.id] # => [1, 2] p3 = Purchase.where(total: 5.99.to_d).first_or_create p4 = Purchase.where(total: 5.99.to_d).first_or_create [p3.id, p4.id] # => [1, 1] 

无论小数或浮点数,Ruby和postgresql都没有完全代表5.99的问题:

 5.99.to_s # => "5.99" 5.99.to_d.to_s # => "5.99" 5.99 == 5.99.to_d # => true SELECT CAST(5.99 AS DECIMAL) AS decimal, CAST(5.99 AS FLOAT) AS float; # decimal | float # ---------+------- # 5.99 | 5.99 # (1 row) SELECT CAST(5.99 AS DECIMAL) = CAST(5.99 AS FLOAT) AS equal; # equal # ------- # t # (1 row) 

最重要的是,一些其他值不会发生这种情况:

 p5 = Purchase.where(total: 5.75).first_or_create p6 = Purchase.where(total: 5.75).first_or_create p7 = Purchase.where(total: 5.75.to_d).first_or_create [p5.id, p6.id, p7.id] # => [3, 3, 3] 

结果certificate这是铁轨的回归。 它可以用5.0.0.1重现??? 并且已经过了5.1.0.0 ???


我把它分成两半,发现这个提交是修复问题的提交。 这是相关问题 。

修复似乎是停止使用pg gem的float编码器。