阅读有关数字数据类型的 Postgresql 文档
让我想到了这个问题:为什么我会在数据类型Float
(SQL 标准)和Numeric
Postgresql 中得到这些意外结果?
例如:
CREATE TEMP TABLE testnum (a numeric, b float);
INSERT INTO testnum VALUES (100,100);
INSERT INTO testnum VALUES (9*9*9,9*9*9);
INSERT INTO testnum VALUES (9^9^9,9^9^9);
SELECT (a/3)*3 AS numeric, (b/3) * 3 AS float FROM testnum;
SELECT (a/5)*5 AS numeric, (b/5) * 5 AS float FROM testnum;
然后运行
SELECT (a/3)*3 AS numeric, (b/3) * 3 AS float FROM testnum;
numeric | float
99.9999999999999999 | 100
729.0000000000000000 | 729
在这个测试中Float
看起来比Numeric
.
对于货币或库存数量等精确数值,哪一种是合适的数据类型?
您正在成为隐式类型转换的受害者。当其中一个操作数是
numeric
和另一个integer
时,整数操作数将被强制转换为numeric
,结果将是numeric
。由于numeric
具有严格定义的精度,因此尝试在不四舍五入的情况下为其分配小数点后具有无限位数的值(100/3 产生)将导致截断。同样的逻辑适用于乘法,现在一个操作数不是您似乎期望的 33.333...(具有无限序列的“3”),而是定义的精度numeric
33.333...3(有限序列"3"s),自然产生 99.999...9 -- 一个有限序列当其中一个操作数是
float
和另一个integer
时,整数操作数将被强制转换为float
,结果将是float
。由于float
具有近似精度,因此它能够以不同的方式处理 33.333... 和 99.999...,最终得出近似值 100。至于
该手册为您提供了所需的确切答案:
它没有说的是您应该通过使用适合您的业务规则的显式类型转换和舍入来控制每个步骤的计算。