奇怪的舍入问题 [英] Weird rounding issue
问题描述
使用小数和浮动数字会发生奇怪的事情,我无法理解为什么或在哪里(ruby / rails / postgresql)。
给定一个 :
p1 = Purchase.where(购买总数:5.99).first_or_create
p2 = Purchase.where(total:5.99).first_or_create
[p1.id,p2.id]#=> [1,2]
p3 = Purchase.where(合计:5.99.to_d).first_or_create
p4 = Purchase.where(合计:5.99.to_d).first_or_create
[p3.id,p4.id]#=> [1,1]
无论是小数还是小数,Ruby和postgresql都没有问题,
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等于;
#等于
#-------
#t
#(1 row)
最重要的是,这不会发生一些其他的值:
<$ c $ p> = 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]
在轨道上是一个回归。用5.0.0.1重现并已经过了5.1.0.0 ???。
我将它平分,发现 this commit 是解决问题的方法。这是相关的问题。
修复似乎是停止使用pg gem的浮点编码器。
Something very weird is happening with decimals and floating numbers and I can't understand why or where (ruby/rails/postgresql).
Given a purchases table with a decimal column - total:
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]
Both Ruby and postgresql have no problem representing 5.99 exactly, no matter if decimals or floats:
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)
To top it all off, this doesn't happen with some other values:
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]
This turned out to be a regression in rails. It's reproducible with 5.0.0.1??? and is gone by 5.1.0.0???.
I bisected it and found this commit to be the one that fixes the issue. This is the related issue.
The fix seems to be to stop using the pg gem's float encoder.
这篇关于奇怪的舍入问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!