Skip to content

PostgreSQL 浮点类型 ​

本文介绍了 PostgreSQL 中的 两种浮点数据类型:REAL 和 DOUBLE PRECISION

数据类型real和double precision是不精确的、变精度的数字类型。 实际上,这些类型是 IEEE 754 标准二进制浮点数算术(分别对应单和双精度)的一般实现, 外加下层处理器、操作系统和编译器对它的支持。

不精确意味着一些数值不能精确地转换成内部格式并且是以近似值存储的, 因此存储后再把数据打印出来可能有一些差异。 处理这些错误以及这些错误是如何在计算中传播的属于数学和计算机科学的一个完整的分支, 我们不会在这里进一步讨论它,这里的讨论仅限于如下几点:

  • 如果你要求精确的计算(比如计算货币金额),应使用numeric类型。
  • 如果你想用这些类型做任何重要的复杂计算, 尤其是那些你对范围情况(无穷/下溢)严重依赖的事情,那你应该仔细评诂你的实现。
  • 拿两个浮点数值进行相等性比较可能不像你想像那样运转。

在大多数平台上,real类型的范围是至少 1E-37 到 1E+37, 精度至少是 6 位小数。double precision的范围通常是 1E-307 到 1E+308, 精度是至少 15 位数字。太大或者太小的数值都会导致错误。如果输入数据的精度太高, 那么将会发生圆整。太接近零的数字,如果无法与零值的表现形式相区分就会产生下溢错误。

注意

当一个浮点数值转化为文本输出时,extra_float_digits 设置控制额外有效数字的位数。默认值是0,PostgreSQL 支持的平台上的输出是一样的。增加这个值产生的输出将更精确的表示存储值, 但是可能不利于移植。


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

sql
Infinity`
`-Infinity`
`NaN

这些值分别表示 IEEE 754 特殊值"正无穷大"、"负无穷大"、 "不是一个数字"。在不遵循 IEEE 754 浮点算术的机器上, 这些值的含义可能不是预期的。如果在 SQL 命令里把这些数值当作常量写, 你必须在它们周围放上单引号,像这样:UPDATE table SET x = 'Infinity'。 输入时,这些值是以大小写无关的方式识别的。

注意

IEEE754 声明NaN不应该等于任何其他浮点值(包括NaN)。 为了能存储浮点值,并且使用 Tree 索引,PostgreSQL 认为NaN 相等,并且大于所有非NaN值。

PostgreSQL 还支持 SQL 标准表示法float 和float(*p*)用于声明非精确的数值类型。 其中的*p*声明以***二进制***位表示的最低可接受精度。 在选取real类型的时候,PostgreSQL 接受 float(1)到float(24),在选取double precision 的时候,接受float(25)到float(53)。 在允许范围之外的*p*值将导致一个错误。 没有声明精度的float将被当作double precision。

注意

假设real和double precision 分别有 24 和 53 个二进制位的位数对 IEEE 标准的浮点实现来说是正确的。在非 IEEE 平台上, 这个数值可能略有偏差,但是为了简化,我们在所有平台上都用了同样的*p*值范围。

PostgreSQL real 数据类型介绍 ​

PostgreSQL 中的 real 数据类型是一种浮点数类型,它可以存储单精度浮点数(32 位)。

语法 ​

定义 real 数据类型的语法如下:

sql
column_name real

使用场景 ​

real 数据类型通常用于存储具有小数部分的数值,比如温度、速度、价格等。它在科学、工程、金融等领域广泛使用。

与 double precision 数据类型相比,real 数据类型使用更少的存储空间,但精度稍低。如果您需要更高的精度,可以使用 double precision 数据类型。

示例 ​

下面是两个使用 real 数据类型的示例:

示例 1 ​

在这个示例中,我们将创建一个名为 temperature 的表,其中包含一个名为 value 的 real 列。value 列存储温度值。

sql
CREATE TABLE temperature (
    id SERIAL PRIMARY KEY,
    value REAL
);

INSERT INTO temperature (value) VALUES (24.5);
INSERT INTO temperature (value) VALUES (26.8);

现在,我们可以查询 temperature 表,并计算所有温度值的平均值:

sql
SELECT AVG(value) FROM temperature;

结果为:

bash
 avg
--------
 25.65
(1 row)

示例 2 ​

在这个示例中,我们将创建一个名为 product 的表,其中包含一个名为 price 的 real 列。price 列存储产品的价格。

sql
CREATE TABLE product (
    id SERIAL PRIMARY KEY,
    name VARCHAR(50),
    price REAL
);

INSERT INTO product (name, price) VALUES ('Product A', 19.99);
INSERT INTO product (name, price) VALUES ('Product B', 29.99);

现在,我们可以查询 product 表,并计算所有产品价格的总和:

sql
SELECT SUM(price) FROM product;

结果为:

bash
 sum
--------
 49.98
(1 row)

PostgreSQL double precision 数据类型介绍 ​

PostgreSQ L 是一种强大的关系型数据库管理系统,支持许多数据类型,包括 double precision。

double precision 数据类型是一种精确度为 15-17 位数字的浮点数,具有更高的精度和范围比 float 数据类型。它占用 8 个字节的存储空间。

语法 ​

在 PostgreSQL 中,可以使用以下语法声明 double precision 类型的列:

sql
column_name DOUBLE PRECISION

使用场景 ​

由于 double precision 数据类型提供更高的精度和范围,因此它通常用于需要更高精度计算的情况,例如科学计算、工程和金融应用程序等。

示例 ​

下面是两个 double precision 数据类型的示例,其中包括创建一个包含 double precision 列的表,并插入一些数据行。

创建一个名为 employees 的表,其中包含 id、name 和 salary 列,其中 salary 的数据类型为 double precision,

sql
CREATE TABLE employees (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    salary DOUBLE PRECISION NOT NULL
);

插入一些员工数据行,

sql
INSERT INTO employees (name, salary) VALUES
    ('John Doe', 95000.50),
    ('Jane Smith', 128000.75),
    ('Bob Johnson', 75000.25);

接下来,我们可以查询 employees 表并使用 ROUND 函数对 salary 列进行四舍五入:

sql
-- 查询 `employees` 表中的数据,并将 `salary` 列进行四舍五入
SELECT name, ROUND(salary) as rounded_salary
FROM employees;

结果如下:

bash
 name         | rounded_salary
--------------+----------------
 John Doe     | 95001
 Jane Smith   | 128001
 Bob Johnson  | 75000

结论 ​

real 数据类型是 PostgreSQL 的一种有用的浮点数类型,它在存储需要小数部分的数值时非常有用。虽然它的精度比 double precision 数据类型稍低,但它使用更少的存储空间,因此在某些情况下可以更有效地使用存储空间。

double precision 提供更高的精度和范围,通常用于需要更高精度计算的情况,例如科学计算、工程和金融应用程序等。