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

如何实现溢出时取低64位的64位整数算术运算(+、-、*)?

实现符合128位运算取低64位的64位整数加减乘运算

完全可行。你的需求本质是让64位有符号整数运算溢出时,结果等效于先转换为128位有符号整数执行运算,取低64位后再转回64位有符号整数的结果,可通过以下两种方式实现,取决于编译器是否支持128位整数类型。

方法一:利用编译器原生128位整数支持

GCC、Clang等主流编译器都支持__int128(128位有符号整数)扩展类型,直接用它就能完成需求,代码简洁且高效:

加法

#include <stdint.h>

int64_t safe_add(int64_t a, int64_t b) {
    return (int64_t)((__int128)a + (__int128)b);
}

减法

int64_t safe_sub(int64_t a, int64_t b) {
    return (int64_t)((__int128)a - (__int128)b);
}

乘法

int64_t safe_mul(int64_t a, int64_t b) {
    return (int64_t)((__int128)a * (__int128)b);
}

编译器会自动将64位整数提升到128位运算,再截断低64位转回64位,完全符合要求,同时避免了有符号整数溢出的未定义行为。

方法二:无符号运算兼容方案(不依赖__int128)

如果需要兼容不支持__int128的编译器,可利用无符号整数运算的确定性环绕特性(溢出时自动取低64位),再将结果转回有符号整数,效果和128位运算取低64位一致:

加法

int64_t safe_add(int64_t a, int64_t b) {
    uint64_t ua = (uint64_t)a;
    uint64_t ub = (uint64_t)b;
    return (int64_t)(ua + ub);
}

减法

int64_t safe_sub(int64_t a, int64_t b) {
    uint64_t ua = (uint64_t)a;
    uint64_t ub = (uint64_t)b;
    return (int64_t)(ua - ub);
}

乘法(手动拆分计算)

乘法需手动拆分64位整数为32位段,通过32位运算组合出低64位结果:

int64_t safe_mul(int64_t a, int64_t b) {
    uint32_t ah = (uint32_t)(a >> 32);
    uint32_t al = (uint32_t)a;
    uint32_t bh = (uint32_t)(b >> 32);
    uint32_t bl = (uint32_t)b;

    uint64_t al_bl = (uint64_t)al * bl;
    uint64_t al_bh = (uint64_t)al * bh;
    uint64_t ah_bl = (uint64_t)ah * bl;

    // 累加各部分得到低64位,高32位的乘积部分不影响低64位结果
    uint64_t res = al_bl + (al_bh << 32) + (ah_bl << 32);
    return (int64_t)res;
}

关键说明

  • 无符号整数运算的环绕行为是C标准明确规定的,因此上述兼容方案完全可移植,不会触发未定义行为。
  • 将无符号运算结果转回有符号整数时,得到的就是128位有符号运算后低64位的符号解释,和需求完全匹配。
  • 对于支持__int128的平台,优先使用方法一,编译器会生成最优机器码(比如x86-64平台会直接利用mulq指令生成128位乘积,再截断低64位)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 21:29:50