You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中双精度数值的舍入机制及精确存储查询问题

PostgreSQL中double precision的显示问题

我了解double precision的工作原理(包括指数、尾数、精度随数值变化、部分数值无法精确存储等特性),目前正在撰写相关主题的博客。但在使用PostgreSQL时,发现它会对这类数值做舍入处理。

配置参数extra_float_digits=1(或更大值)本该允许PostgreSQL显示所有位数,但实际效果并非如此。

比如,1.1无法用double precision精确存储,它会被近似为1.100000000000000088817841970012523233890533447265625——这是最接近的可存储值,相邻步长约为2.2204460492 × 10^−16。为什么没法直接可视化这个存储的精确值?

我猜测代码会把数值舍入到10^-15位,因为这是该数量级下的最大精度,但没法确认。

我有三个问题:

  • PostgreSQL是否会对数值进行舍入?
  • 是否可以查看存储的精确值?
  • 是否实际已能查看,但我在使用PSQL时操作有误?

测试操作及结果

我设置了:

SET extra_float_digits=3;

执行查询:

SELECT 1.1::float8;

返回结果:

float8
--------
    1.1

结果为1.1,并非实际存储的精确值。

同样执行:

SELECT 1.1::float8::varchar;

返回结果:

varchar
---------
 1.1

若直接查询精确值:

SELECT 1.100000000000000088817841970012523233890533447265625::float8;

返回结果:

float8
--------
    1.1

问题解答

  1. PostgreSQL是否会对数值进行舍入?
    是的。PostgreSQL在显示float8(即double precision)类型的值时,会自动舍入为最短的十进制字符串——这个字符串转换回float8时能还原出原始的二进制存储值。这种处理是为了避免冗余位数,同时保证数值的可逆性,并非丢失了存储的精确值。

  2. 是否可以查看存储的精确值?
    可以。你需要用to_char函数指定足够多的小数位数,或者通过查看二进制原始值来推导精确十进制表示:

  • 使用to_char显示精确值:
SELECT to_char(1.1::float8, 'FM9999999999999999999999999999');

该查询会返回1.100000000000000088817841970012523233890533447265625。

  • 查看二进制原始值:
SELECT encode(cast(1.1::float8 as bytea), 'hex');

得到的十六进制值可以转换为对应的十进制精确值。

  1. 是否实际已能查看,但我在使用PSQL时操作有误?
    是的。你之前的操作没有采用能显示全部精确位数的方法。extra_float_digits参数控制的是显示的额外位数,但它的设计目标是保证数值转换的可逆性,而非强制显示所有二进制位对应的十进制位数。默认的格式化逻辑还是优先输出最短的可逆字符串,所以即使设置了extra_float_digits=3,也不会自动显示全部精确位数。

内容的提问来源于stack exchange,提问作者Arthur Bazin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 03:26:11