2

Postgres 9.0 的文档中所述,数据类型具有 15 个十进制数字的精度和 8 个字节的存储空间,然后近似double precision一个大于bigint存储在字段中的正常(8 个字节)的整数。double precision如果我错了,请纠正我,我说大于正常值bigint,因为如果您尝试将此数字转换为bigint您会收到此错误:

select 211116514527303268704::bigint;
>> ERROR:  bigint out of range

当您尝试将其转换为double precisionandnumeric并比较两者时,您会发现它们是相同的:

select 211116514527303268704::numeric,
211116514527303268704::double precision,
(211116514527303268704::double precision) = (211116514527303268704::numeric);
+-----------------------+----------------------+---------+
|        numeric        |        float8        | boolean |
+-----------------------+----------------------+---------+
| 211116514527303268704 | 2.11116514527303e+20 | t       |
+-----------------------+----------------------+---------+

并使用to_char()函数返回不同的值:

select
trim(to_char((211116514527303268704::double precision),'999,999,999,999,999,999,999')),
trim(to_char((211116514527303268704::numeric),'999,999,999,999,999,999,999'));
+-----------------------------+-----------------------------+
|            text             |            text             |
+-----------------------------+-----------------------------+
| 211,116,514,527,303,270,400 | 211,116,514,527,303,268,704 |
+-----------------------------+-----------------------------+

如您所见,使用 to_char - 数字组合返回的值是正确的,但 to_char - 双精度与double precision2.11116514527303e+20中的指数部分失去一致性

我不确定它是否会影响某些东西,但语言环境lc_numeric是“es_PY.utf8”

在这种情况下实现完全没用,double precision或者保留那些双精度字段是另一种选择?这始终是首选选项,是否有某种类型的转换numeric可以double precision保留所有原始数字?

有关其他信息,我在 CentOS 6 x86-64 服务器上运行了 PostgreSQL 9.0 安装。

4

1 回答 1

1

原因是为了进行相等比较,将分辨率较高的类型转换为分辨率较低的类型。即:在示例中numeric被强制转换为double precision.

演示:

SELECT *
     , num = dp          AS no_cast
     , num::float8 = dp  AS dp_cast
     , num = dp::numeric AS num_cast
FROM  (
   SELECT numeric '211116514527303268705' AS num
        , float8  '211116514527303268705' AS dp
   ) t;

 num                  | dp                    | no_cast | dp_cast | num_cast
----------------------+-----------------------+---------+---------+---------
211116514527303268705 | 2.11116514527303e+020 | t       | t       | f

float8是 的别名double precision
请注意,对于其他计算,例如加法,具有更高分辨率的类型是结果 - 这是逻辑必需的。boolean(无论如何,这里的结果。)

于 2015-05-28T17:10:27.190 回答