↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

百科 / 数据类型 / 数值

double precision

双精度浮点数(8 字节)

当前查看 PostgreSQL 18.6。

PG10–20 核心源码清单。类型转换与操作符类列出源码显式声明的关系;缺少记录不能排除通过其他机制进行转换或使用索引。

定义

SQL 名称与别名: float8, float

双精度浮点数(8 字节)

double precision
目录名称
pg_catalog.float8
类型 OID
701
类型种类
基础类型
声明长度
8 字节
存储策略
plain
输入函数
float8in
输出函数
float8out
手册中的声明
double precision
存储大小
8 字节
手册说明
可变精度,不精确
范围
15 位十进制有效数字

中文手册

阅读完整手册章节

阅读来源定义

8.1. 数值类型

数值类型包括二字节、四字节和八字节整数,四字节和八字节浮点数,以及可选精度的十进制数。表 8.2 列出了可用类型。

表 8.2:数值类型

名字 存储大小 说明 范围
smallint 2 字节 小范围整数 -32768 到 +32767
integer 4 字节 整数的常用选择 -2147483648 到 +2147483647
bigint 8 字节 大范围整数 -9223372036854775808 到 +9223372036854775807
decimal 可变 用户指定精度,精确 小数点前最多 131072 位,小数点后最多 16383 位
numeric 可变 用户指定精度,精确 小数点前最多 131072 位,小数点后最多 16383 位
real 4 字节 可变精度,不精确 6 位十进制有效数字
double precision 8 字节 可变精度,不精确 15 位十进制有效数字
smallserial 2 字节 小型自增整数 1 至 32767
serial 4 字节 自增整数 1 至 2147483647
bigserial 8 字节 大型自增整数 1 至 9223372036854775807

数值类型常量的语法见第 4.1.2 节。数值类型拥有完整的对应算术运算符和函数,更多信息见第 9 章。以下各节详细介绍这些类型。

8.1.1. 整数类型

smallint、integer 和 bigint 存储不含小数部分的整数,取值范围各不相同。尝试存储超出允许范围的值会报错。

integer 是常用选择,在取值范围、存储大小和性能之间取得了最佳平衡。smallint 通常仅在磁盘空间非常紧张时使用;bigint 则用于 integer 范围不足的情况。

SQL 仅规定了 integer(或 int)、smallint 和 bigint 这几种整数类型。类型名 int2、int4 和 int8 是扩展,一些其他 SQL 数据库系统也使用它们。

8.1.2. 任意精度数值

numeric 可以存储位数非常多的数值,尤其推荐用于货币金额和其他要求精确的数量。numeric 运算会在可能时产生精确结果,例如加法、减法和乘法。不过,与整数类型或下一节介绍的浮点类型相比,numeric 运算非常慢。

下文使用以下术语:numeric 的精度是整个数值的有效数字总数,即小数点两侧数字的总位数;小数位数是小数点右侧小数部分的十进制数字位数。例如,23.5141 的精度为 6,小数位数为 4。整数可以视为小数位数为零。

numeric 列的最大精度和最大小数位数都可以配置。声明 numeric 类型列时使用以下语法:

NUMERIC(precision, scale)

精度必须为正数,小数位数可以为正数或负数,见下文。也可以写为:

NUMERIC(precision)

选择小数位数为 0。指定:

NUMERIC

不指定精度或小数位数时,将创建一个“不受约束的 numeric”列,可存储任意长度的数值,但仍受实现上限约束。这类列不会将输入值强制转换为特定的小数位数,而声明了小数位数的 numeric 列会强制转换为该位数。(SQL 标准要求默认小数位数为 0,即强制采用整数精度。我们认为这样不太实用。如果需要兼容其他数据库,应始终显式指定精度和小数位数。)

注意

numeric 类型声明可显式指定的最大精度为 1000。未限定精度的 numeric 列受表 8.2 所述限制约束。

如果待存储值的小数位数大于列声明的小数位数,系统会将该值舍入到指定的小数位数。随后,如果小数点左侧的位数超过声明精度减去声明小数位数的结果,就会报错。例如,声明为下列形式的列:

NUMERIC(3, 1)

会将值舍入到 1 位小数,并可存储 -99.9 至 99.9 之间的值,包含两端。

从 PostgreSQL 15 开始,允许声明小数位数为负的 numeric 列。此时,数值会在小数点左侧进行舍入。精度仍表示未被舍入部分的最大位数。因此,声明为下列形式的列:

NUMERIC(2, -3)

会将值舍入到最接近的千位,并可存储 -99000 至 99000 之间的值,包含两端。还允许声明大于精度的小数位数。这样的列只能保存小数值,并要求小数点右侧紧接的零的位数,至少为声明的小数位数减去声明的精度。例如,声明为下列形式的列:

NUMERIC(3, 5)

会将值舍入到 5 位小数,并可存储 -0.00999 至 0.00999 之间的值,包含两端。

注意

PostgreSQL 允许 numeric 类型声明中的小数位数为 -1000 到 1000 之间的任意值。但 SQL 标准要求它介于 0 和精度之间。使用此范围以外的小数位数,可能无法移植到其他数据库系统。

numeric 值在物理存储时不会保留多余的前导零或尾随零。因此,列声明的精度与小数位数是最大限制,而非固定分配的空间。(从这一点看,numeric 更像 varchar(n),而非 char(n)。)实际存储每四位十进制数字需要两个字节,另加三到八个字节的开销。

除普通数值外,numeric 类型还有几个特殊值:


Infinity
-Infinity
NaN

这些值取自 IEEE 754 标准,分别表示“正无穷”“负无穷”和“非数”。在 SQL 命令中将它们写成常量时,必须加引号,例如 UPDATE table SET x = '-Infinity'。输入识别时不区分大小写,无穷值也可写为 inf 和 -inf。

无穷值遵循数学上的预期。例如,Infinity 加任意有限值仍为 Infinity,Infinity 加 Infinity 也如此;但 Infinity 减 Infinity 得到 NaN(非数),因为此运算没有明确的数学含义。无穷值只能存储在未限定精度的 numeric 列中,因为从概念上说,它超出了任何有限精度限制。

NaN(非数)用于表示未定义的计算结果。通常,输入包含 NaN 的运算会产生另一个 NaN。唯一例外是:在其他输入不变的情况下,如果将 NaN 替换为任意有限或无限数值都会得到相同结果,那么对 NaN 也返回该结果。(例如,NaN 的零次方为一。)

注意

在“非数值”概念的大多数实现中,NaN 不被视为与任何其他数值相等(包括 NaN)。为了使数值能够排序并用于树形索引,PostgreSQL 将 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)

8.1.3. 浮点类型

real 和 double precision 是非精确、可变精度的数值类型。在当前支持的所有平台上,在底层处理器、操作系统和编译器支持的范围内,它们分别实现 IEEE 754 二进制浮点运算标准的单精度和双精度格式。

不精确意味着某些值无法精确转换为内部格式,只能存储为近似值,因此存储后再取出时可能出现细微差异。如何处理这些误差及其在计算中的传播,是数学和计算机科学中的一个完整分支,此处不作展开,仅说明以下几点:

  • 如果需要精确存储和计算(例如处理货币金额),请改用 numeric 类型。
  • 如果要使用这些类型进行重要的复杂计算,尤其是依赖边界情况(无穷大、下溢)的特定行为时,应仔细评估其实现。
  • 比较两个浮点值是否相等,结果可能并不总是符合预期。

在当前支持的所有平台上,real 的取值范围约为 1E-37 到 1E+37,精度至少为 6 位十进制数字。double precision 的取值范围约为 1E-307 到 1E+308,精度至少为 15 位。值过大或过小都会报错;输入精度过高时可能发生舍入。过于接近零、无法表示为区别于零的数值时,会报下溢错误。

默认情况下,浮点值以最短的精确十进制表示形式输出为文本;生成的十进制值与实际存储的二进制值之间的距离,小于它与相同二进制精度下任何其他可表示值之间的距离。(不过,目前输出值绝不会恰好位于两个可表示值的正中间,以避开输入例程未正确遵守舍入到最近偶数规则这一常见缺陷。)对于 float8 值,这种表示最多使用 17 位十进制有效数字;对于 float4 值,最多使用 9 位。

注意

这种最短精确输出格式的生成速度,远高于历史上使用的舍入格式。

为兼容旧版 PostgreSQL 生成的输出,并允许降低输出精度,可以使用 extra_float_digits 参数改为选择舍入后的十进制输出。设置为 0 会恢复此前的默认行为,将值舍入为 6 位(float4)或 15 位(float8)十进制有效数字。负值会进一步减少位数;例如,-2 会分别将输出舍入为 4 位或 13 位。

任何大于 0 的 extra_float_digits 值都会选择最短精确格式。

注意

过去,需要精确值的应用必须将 extra_float_digits 设为 3 才能获得这些值。为了最大限度地兼容不同版本,它们应继续这样设置。

除普通数值外,浮点类型还有几个特殊值:


Infinity
-Infinity
NaN

这些值分别表示 IEEE 754 特殊值“正无穷”“负无穷”和“非数”。在 SQL 命令中将它们写成常量时,必须加引号,例如 UPDATE table SET x = '-Infinity'。输入识别时不区分大小写,无穷值也可写为 inf 和 -inf。

注意

IEEE 754 规定,NaN 不应与任何其他浮点值相等(包括 NaN)。为了使浮点值能够排序并用于树形索引,PostgreSQL 将 NaN 值视为彼此相等,且大于所有非 NaN 值。

PostgreSQL 也支持 SQL 标准的 float 和 float(p) 记法来指定非精确数值类型。p 表示可接受的最小二进制位精度。float(1) 到 float(24) 选择 real 类型,float(25) 到 float(53) 选择 double precision。p 超出允许范围会报错;不指定精度的 float 等同于 double precision。

8.1.4. 序列类型

注意

本节介绍 PostgreSQL 特有的自动递增列创建方法。另一种方法是使用 SQL 标准的标识列特性,参见第 5.3 节。

smallserial、serial 和 bigserial 并非真正的类型,而是用于创建唯一标识符列的便捷记法,类似于其他一些数据库支持的 AUTO_INCREMENT 属性。在当前实现中,指定:

CREATE TABLE tablename (
    colname SERIAL
);

等价于指定:

CREATE SEQUENCE tablename_colname_seq AS integer;
CREATE TABLE tablename (
    colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;

这样就创建了一个 integer 列,并安排由序列生成器提供默认值。NOT NULL 约束保证无法插入空值。(多数情况下还应增加 UNIQUE 或 PRIMARY KEY 约束,防止意外插入重复值,但系统不会自动添加。)最后,序列被标记为归该列所有,因此删除列或表时,序列也会被删除。

注意

由于 smallserial、serial 和 bigserial 使用序列实现,即使从未删除任何行,列中出现的值序列也可能存在“空洞”或间隙。即便包含所分配值的行从未成功插入表列,从序列分配的值仍已被“用掉”。例如,插入事务回滚时就会发生这种情况。详见第 9.17 节的 nextval()。

要将序列的下一个值插入 serial 列,应让该列使用默认值。可以在 INSERT 的列列表中省略此列,也可以使用 DEFAULT 关键字。

serial 与 serial4 等价,都会创建 integer 列。bigserial 与 serial8 的工作方式相同,只是创建 bigint 列。如果预计表的整个生命周期内使用的标识符超过 2^31 个,应使用 bigserial。smallserial 与 serial2 也采用相同方式,但创建 smallint 列。

为 serial 列创建的序列会在所属列被删除时自动删除。也可以只删除序列而保留列,但这会强制移除列的默认值表达式。

系统目录属性

此构建的源码初始化值。字段含义参见 pg_type 。包含头文件默认值;依赖构建的常量保留符号形式,不作为服务器运行时实测。

oid
701
descr
double-precision floating point number, 8-byte storage
typacl
_null_
typlen
8
typelem
0
typname
float8
typsend
float8send
typtype
b
typalign
d
typarray
0
typbyval
FLOAT8PASSBYVAL
typdelim
','
typinput
float8in
typmodin
-
typndims
0
typowner
POSTGRES
typrelid
0
typmodout
-
typoutput
float8out
typtypmod
-1
typanalyze
-
typdefault
_null_
typnotnull
f
typreceive
float8recv
typstorage
p
typbasetype
0
typcategory
N
typcollation
0
typisdefined
t
typnamespace
pg_catalog
typsubscript
-
typdefaultbin
_null_
array_type_oid
1022
typispreferred
t
array_type_name
_float8

类型转换 11

与此类型相关的显式 pg_cast 记录。PostgreSQL 还支持 pg_cast 之外的类型转换,缺少记录不能证明转换不可能。

源类型目标类型转换上下文转换方式函数
int8float8隐式函数float8(int8)
int2float8隐式函数float8(int2)
int4float8隐式函数float8(int4)
float4float8隐式函数float8(float4)
float8int8赋值函数int8(float8)
float8int2赋值函数int2(float8)
float8int4赋值函数int4(float8)
float8float4赋值函数float4(float8)
float8numeric赋值函数numeric(float8)
numericfloat8隐式函数float8(numeric)
jsonbfloat8显式函数float8(jsonb)

运算符重载 42

每种操作数签名均为独立重载。实现函数和返回类型来自同一源码构建。

运算符左操作数右操作数返回类型含义实现函数
-无(一元)float8float8取相反数float8um
+float8float8float8相加float8pl
-float8float8float8相减float8mi
/float8float8float8相除float8div
*float8float8float8相乘float8mul
@无(一元)float8float8绝对值float8abs
|/无(一元)float8float8平方根dsqrt
||/无(一元)float8float8立方根dcbrt
=float8float8bool等于float8eq
<>float8float8bool不等于float8ne
<float8float8bool小于float8lt
<=float8float8bool小于等于float8le
>float8float8bool大于float8gt
>=float8float8bool大于等于float8ge
*moneyfloat8money相乘cash_mul_flt8
/moneyfloat8money相除cash_div_flt8
*float8moneymoney相乘flt8_mul_cash
^float8float8float8乘方dpow
+float4float8float8相加float48pl
-float4float8float8相减float48mi
/float4float8float8相除float48div
*float4float8float8相乘float48mul
=float4float8bool等于float48eq
<>float4float8bool不等于float48ne
<float4float8bool小于float48lt
>float4float8bool大于float48gt
<=float4float8bool小于等于float48le
>=float4float8bool大于等于float48ge
+float8float4float8相加float84pl
-float8float4float8相减float84mi
/float8float4float8相除float84div
*float8float4float8相乘float84mul
=float8float4bool等于float84eq
<>float8float4bool不等于float84ne
<float8float4bool小于float84lt
>float8float4bool大于float84gt
<=float8float4bool小于等于float84le
>=float8float4bool大于等于float84ge
*intervalfloat8interval相乘interval_mul
*float8intervalinterval相乘mul_d_interval
/intervalfloat8interval相除interval_div
+无(一元)float8float8一元正号float8up

操作符类 5

声明输入类型与此类型相符的操作符类。多态操作符类、类型转换和表达式索引还可能提供其他索引路径;不能仅凭此表判断是否支持索引。

操作符类索引方法输入类型操作符族默认存储类型
float8_opsbtreefloat8btree/float_ops是与输入类型相同
float8_opshashfloat8hash/float_ops是与输入类型相同
float8_minmax_opsbrinfloat8brin/float_minmax_ops是float8
float8_minmax_multi_opsbrinfloat8brin/float_minmax_multi_ops否float8
float8_bloom_opsbrinfloat8brin/float_bloom_ops否float8

版本比较

PostgreSQL 17.11 → 18.6。属性比较不包含构建标识和说明正文;原始目录字段与源描述保留原文。

这两个样本的系统目录和结构化属性没有变化。

这些构建的文档也有差异,请查看对应版本的手册定义。

文档与源码

构建
18.6 · https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2
指纹
555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f

相关条目

全部数据类型 · 下载此版本 JSON · 最早收录的样本不代表该类型的实际引入版本。