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

如何在PostgreSQL中实现bigint的环绕式算术运算(无溢出)?

在PostgreSQL的bigint列上实现64位整数环绕式运算的方法

可以实现标准的64位整数环绕式运算,以下是针对不同场景的具体方案:

一、普通加减乘运算的环绕实现

PostgreSQL默认会检测bigint溢出并抛出错误,但利用bit(64)类型的自动溢出环绕特性,可以高效实现目标行为:

加法环绕

SELECT (9223372036854775807::bit(64) + 1::bit(64))::bigint;
-- 输出:-9223372036854775808

乘法环绕

SELECT (9223372036854775807::bit(64) * 2::bit(64))::bigint;
-- 输出:-2

这种方法依赖原生位运算实现,性能接近纯64位整数运算,远优于基于numeric或模运算的方案。

二、SUM聚合的环绕实现

PostgreSQL默认的SUM会将bigint转为numeric类型计算以避免溢出,要实现环绕式SUM,需自定义聚合函数:

  1. 先创建环绕加法的辅助函数:
CREATE OR REPLACE FUNCTION bigint_wrap_add(a bigint, b bigint)
RETURNS bigint AS $$
BEGIN
    RETURN (a::bit(64) + b::bit(64))::bigint;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
  1. 基于该函数创建自定义聚合:
CREATE AGGREGATE sum_wrap(bigint) (
    SFUNC = bigint_wrap_add,
    STYPE = bigint,
    INITCOND = '0'
);
  1. 使用自定义聚合实现环绕求和:
SELECT sum_wrap(id) FROM (VALUES(9223372036854775807), (9223372036854775807)) AS t(id);
-- 输出:-2

这个自定义聚合全程基于bigint和位运算,性能与原生聚合接近,完全符合补码溢出环绕的标准行为。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:27:38