奇怪的舍入问题 [英] Weird rounding issue

查看:195
本文介绍了奇怪的舍入问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用小数和浮动数字会发生奇怪的事情,我无法理解为什么或在哪里(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆