postgres双精度

时间:2011-08-31 09:42:36

标签: postgresql

select round(product_qty * 100) - product_qty as test, 
       id, product_qty 
from stock_move 
where product_id=63 
  and state='done' 
  and id=45058;
        test         |  id   | product_qty 
54.45                | 45058 |        0.55
(1 ligne)
select round(product_qty * 100) - (product_qty*100) as test, 
       id, 
       product_qty 
from stock_move 
where product_id=63 
  and state='done' 
  and id=45058;
        test         |  id   | product_qty 

 -7.105427357601e-15 | 45058 |        0.55
(1 ligne)

有人能解释一下这些结果吗?

2 个答案:

答案 0 :(得分:3)

像pg中的双精度字段这样的浮点表示本质上受到舍入误差的影响。 This paper给出了很好的数学介绍。

如何处理这些舍入错误取决于您的应用程序,并在以下各项之间变化:

  • 与他们一起生活,例如忽略他们 - 格式化为%.2f,错误将变得不可见。只要确保你理解所有该选择的后果!!
  • 将数据类型切换为设计不受舍入问题影响的内容 - 请查看pg的money类型和exact numeric types

后者应该是首选方法,尤其是在您的应用程序处理资金的情况下。

答案 1 :(得分:1)

您获得这些结果是因为product_qty*100具有与round(product_qty * 100)不同的IEEE-754二进制表示形式:

without round : 100000001001011100000000000000000000000000000000000000000000001
with round    : 100000001001011100000000000000000000000000000000000000000000000

很容易看出55应该表示为1,71875 * 2 5 (与圆形一样),但由于浮点运算product_qty*100略有不同。

如果您仍想使用浮点数,那么我建议您阅读“每个计算机科学家应该了解的关于浮点运算的文章”论文,或者只是以任意精度切换到numeric类型。