PostgreSQL bigint过大?

3

运行

在 x86_64-pc-linux-gnu 上的 PostgreSQL 11.4 (Debian 11.4-1.pgdg90+1),由 gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516 编译,为 64 位。

我尝试了这个语句:

SELECT CAST (2^63-1 as bigint);

但得到了一个意外的错误信息:

大整数超出范围

奇怪的是,如果我将指数形式替换为它的整数等价形式:

SELECT CAST (9223372036854775807 as bigint)

它按预期工作。我想这只是因为我没有正确理解事情。FWIW,我可以使用的最大指数符号中的数字是:

SELECT CAST (2^63-513 as bigint);

任何更大的值都会出现相同的错误。

我对PostgreSQL如何进行指数运算的方式存在疑问,或者说它被转换成浮点型再转回来,从而产生舍入/截断误差?

2个回答

5

是的,它正在转换为双精度,因此您会看到那些舍入误差:

select pg_typeof(2^63);
    pg_typeof
------------------
 double precision

select pg_typeof(2^63-1);
    pg_typeof
------------------
 double precision

如果您从数字开始,它将有效:


select (2::numeric^63-1)::bigint;
        int8
---------------------
 9223372036854775807


1

power 不是整数操作。它可以使用返回 doublenumeric 的方式工作。

select cast(2^63-1 as bigint);

Expands out as

select cast( (power(2, 63) - 1) as bigint );

power(2, 63)在这里返回一个double,该类型的大小有大约512的不精确度。

如果您改为使用numeric,它将使用numeric

select (power(2::numeric, 63) - 1)::bigint;
            int8         
---------------------
 9223372036854775807

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接