📜  psql 中的浮点精度(1)

📅  最后修改于: 2023-12-03 14:45:40.932000             🧑  作者: Mango

psql 中的浮点精度

在使用 PostgreSQL 数据库时,浮点数的精度是一个需要注意的问题。本文将介绍 psql 中浮点精度的特性和注意事项。

浮点数类型

在 psql 中,有两种常用的浮点数类型:REALDOUBLE PRECISION。它们分别代表单精度浮点数和双精度浮点数。

CREATE TABLE example (
    real_number REAL,
    double_number DOUBLE PRECISION
);
IEEE 754 浮点标准

浮点数在计算机中以 IEEE 754 标准表示。根据这个标准,浮点数被分为三个部分:符号位、指数位和尾数位。不同的浮点数类型在存储空间和精度上会有所不同。

  • REAL 类型使用 4 字节(32 位)存储空间,并提供大约 6 位的十进制数精度。
  • DOUBLE PRECISION 类型使用 8 字节(64 位)存储空间,并提供大约 15 位的十进制数精度。
浮点数精度问题

由于浮点数在二进制和十进制之间的转换存在一定的不准确性,因此在进行浮点数计算时可能会出现精度问题。

精度损失

在进行多次浮点数计算时,每次计算都可能引入一定的精度损失。这是由于计算机无法精确地表示某些十进制数,会产生舍入误差。

SELECT 0.1::REAL + 0.1::REAL + 0.1::REAL = 0.3::REAL;  -- 返回 false
SELECT 0.1::DOUBLE PRECISION + 0.1::DOUBLE PRECISION + 0.1::DOUBLE PRECISION = 0.3::DOUBLE PRECISION;  -- 返回 true

在上述示例中,使用 REAL 类型进行浮点数计算会导致精度损失,而使用 DOUBLE PRECISION 类型则能够得到更准确的结果。

等于号比较

由于浮点数误差的存在,直接使用等于号比较浮点数是否相等往往不可靠。应该考虑使用范围或误差允许的方式进行比较。

SELECT 0.1::REAL + 0.2::REAL = 0.3::REAL;  -- 返回 false
SELECT ABS(0.1::REAL + 0.2::REAL - 0.3::REAL) < 0.000001;  -- 返回 true

上述示例中,我们通过比较浮点数的误差是否小于某个阈值来判断它们是否近似相等。

浮点数精度控制

在 psql 中,可以通过设置运行时参数 extra_float_digits 来控制浮点数的输出精度。

-- 设置显示 2 位额外精度
SET extra_float_digits TO 2;
SELECT 0.1::REAL;  -- 返回 0.100000
SELECT 0.1::DOUBLE PRECISION;  -- 返回 0.100000000000000

-- 恢复默认设置
RESET extra_float_digits;
总结

psql 中的浮点精度受到 IEEE 754 标准的影响,在进行浮点数计算时需要注意可能的精度损失和等于号比较的不确定性。为了控制浮点数的输出精度,可以调整运行时参数 extra_float_digits