postgresql bigint 太大了吗?

postgresql bigint too big?

运行

PostgreSQL 11.4 (Debian 11.4-1.pgdg90+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit

我试过这个语句:

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

但收到意外错误消息:

bigint out of range

奇怪的是,如果我只是将指数形式替换为其等效整数:

SELECT CAST (9223372036854775807 as bigint)

它按预期工作。我想这只是我没有正确理解事情。 FWIW 我可以使用的最大指数表示法是:

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

任何更大的错误都以同样的方式出现。

关于 PostgreSQL 如何求幂,我遗漏了什么?或者,它是否被转换为浮动并返回,我看到 rounding/truncation 错误?

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

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

power 不是整数运算。它适用于 returns a doublenumeric.

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

扩展为

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

power(2, 63) here returns a double 在那个大小下有大约 512 的不精确度。

如果您改为以 numeric 开头,它将使用 numeric

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