PostgreSQL浮点运算和类型

时间:2016-04-27 22:42:30

标签: database postgresql floating-point

我有一个Postgres驱动的应用程序,它将数量四舍五入到下一个(不是最近的)第四个小数位。因此,0.00341变为0.0035。

在实施它时,我遇到了0.0012 甚至被舍入到0.0013的情况,即使它不应该;它甚至是0.0012。事实上,即使ceil()同意,乍一看:

postgres=> SELECT ceil(((0.0012) * 10000)) / 10000;
        ?column?        
------------------------
 0.00120000000000000000
(1 row)

我们知道没有引入任意精度:

postgres=> SELECT (ceil(((0.0012) * 10000)) / 10000) = 0.0012;
 ?column? 
----------
 t
(1 row)

然而,当通过计算得出数字0.0012时,情况会发生变化:

postgres=> SELECT (12::double precision / 60) * 0.006;
 ?column? 
----------
   0.0012
(1 row)

postgres=> SELECT ((12::double precision / 60) * 0.006) = 0.0012;
 ?column? 
----------
 f
(1 row)

看起来计算出的0.0012大于实际0.0012:

postgres=> SELECT ((12::double precision / 60) * 0.006) > 0.0012;
 ?column? 
----------
 t
(1 row)

可以预见,这导致舍入机制将0.0012“向上”舍入为0.0013,如果表达式的计算结果为0.0012,则显然是错误的:

postgres=> SELECT ceil(((12::double precision / 60) * 0.006) * 10000) / 10000;
 ?column? 
----------
   0.0013
(1 row)

所以,显然我在这里遗漏了关于如何评估表达式和/或如何投射数据类型的内容。引入了额外的精度,不应该存在。

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:2)

我看到了我的方式错误。这是PostgreSQL中numeric类型的作业,它是一种任意精度类型,旨在提供精确的计算。

来自http://www.postgresql.org/docs/9.5/static/datatype-numeric.html

  

8.1.2。任意精度数

     

数字类型可以存储具有大量数字的数字   并完全执行计算。特别推荐   存储金额和其他精确度的数量   需要。但是,比较数值的算术非常慢   整数类型,或者描述的浮点类型   下一节。