任意精度数字
类型 numeric 可以存储非常多位的数字。特别建议将它用于货币金额和其它要求计算准确的数量。numeric 值的计算在可能的情况下会得到准确的结果,例如加法、减法、乘法。不过,numeric 类型上的算术运算比整数类型或者下一节描述的浮点数类型要慢很多。
在随后的内容里,使用了下述术语:一个 numeric 的 precision(精度)是整个数中有效位的总数,也就是小数点两边的位数。 numeric 的 scale(刻度)是小数部分的数字位数,也就是小数点右边的部分。因此数字 23.5141 的精度为 6 而刻度为 4。可以认为整数的刻度为零。
numeric 列的最大精度和最大比例都是可以配置的。要声明一个类型为 numeric 的列,可以用下面的语法:
NUMERIC(precision, scale)
精度必须为正数,比例可以为零或者正数。另外:
NUMERIC(precision)
选择比例为 0 。如果使用
NUMERIC
创建一个列时不使用精度或比例,则该列可以存储任何精度和比例的数字值,并且值的范围最多可以到实现精度的上限。一个这种列将不会把输入值转化成任何特定的比例,而带有比例声明的 numeric 列将把输入值转化为该比例(SQL 标准要求缺省的比例是 0,即转化成整数精度。觉得这样做有点没用。如果关心移植性,那最好总是显式声明精度和比例)。
注意
显式指定类型精度时的最大允许精度为 1000。
如果一个要存储的值的比例比列声明的比例高,那么系统将尝试圆整(四舍五入)该值到指定的分数位数。 然后,如果小数点左边的位数超过了声明的精度减去声明的比例,那么抛出一个错误。
数字值在物理上是以不带任何前导或者后缀零的形式存储。 因此,列上声明的精度和比例都是最大值,而不是固定分配的 (在这个方面,numeric 类型更类似于 varchar(*n*), 而不像 char(*n*))。 实际存储要求是每四个十进制位组用两个字节,再加上三到八个字节的开销。
除了普通的数字值之外,numeric 类型允许特殊值 NaN, 表示“不是一个数字”。任何在 NaN 上面的操作都生成另外一个 NaN。 如果在 SQL 命令里把这些值当作一个常量写,必须在其周围放上单引号,例如 UPDATE table SET x = 'NaN'。在输入时,字串 NaN 被识别为大小写无关。
注意
在“不是一个数字”概念的大部分实现中,NaN 被认为不等于任何其他数字值(包括 NaN)。为了允许 numeric 值可以被排序和使用基于树的索引,AntDB 把 NaN 值视为相等,并且比所有非 NaN 值都要大。
类型 decimal 和 numeric 是等效的。两种类型都是 SQL 标准的一部分。
在对值进行圆整时,numeric 类型会圆到远离零的整数,而(在大部分机器上)real 和 double precision 类型会圆到最近的偶数上。例如:
SELECT x,
round(x::numeric) AS num_round,
round(x::double precision) AS dbl_round
FROM generate_series(-3.5, 3.5, 1) as x;
x | num_round | dbl_round
------+-----------+-----------
-3.5 | -4 | -4
-2.5 | -3 | -2
-1.5 | -2 | -2
-0.5 | -1 | -0
0.5 | 1 | 0
1.5 | 2 | 2
2.5 | 3 | 2
3.5 | 4 | 4
(8 rows)




