2011-08-31 146 views
0
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) 

有人可以给我解释一下这些结果?Postgres的双精度

+0

你能告诉我们你想问什么吗? – 2011-08-31 09:45:37

+5

双打计算受四舍五入误差影响,对此不能做太多的处理。很多文章在SO上处理这个主题,使用搜索 – fvu

+3

伙计们,这是一个真正的问题(关于双精度不准确性),但已经通过fvu – Bohemian

回答

3

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

你如何处理这些舍入误差取决于您的应用程序了一下,变化之间:

  • 只是他们如通过某种无视他们的生活 - 格式,导致为%.2f和错误将变得无形。只要确保你明白全部该选择的后果!
  • 将数据类型切换为按设计不受舍入问题影响的内容 - 请查看pg的money类型和exact numeric types

后者应该是首选的方法,特别是在您的应用程序处理资金的上下文中。

+0

+1回答了“每个计算机科学家应该知道的内容”。_ :) –

1

你得到的结果,因为product_qty*100round(product_qty * 100)不同的IEEE-754二进制表示:

without round : 100000001001011100000000000000000000000000000000000000000000001 
with round : 100000001001011100000000000000000000000000000000000000000000000 

可以很容易地看到,55应该表示为1,71875 * 2 (如与轮),但由于浮点运算product_qty*100略有不同。

如果你还想和浮点数一起生活,那么我推荐阅读“每个计算机科学家应该知道的关于浮点运算的论文”,或者只是以任意精度切换到numeric类型。

+0

感谢您的答案 – yannicksoldati