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

在C语言中如何存储int64_t类型相乘结果的低64位?并实现指定imull函数(禁止使用GCC内置函数)

关于C语言int64_t相乘低64位存储的解决方案

嘿,先直接给你答案:当然有办法搞定!而且完全不用依赖GCC内置函数,用标准C就能实现。另外顺便说一句,其实很多时候你直接写int64_t乘法,编译器会自动保留低64位,但因为C标准里有符号整数溢出属于未定义行为,所以严格来说还是用标准方法实现更稳妥。

下面是你要的imull函数的完整实现,我会一步步解释清楚:

函数实现(无编译器依赖)

核心思路是把64位整数拆成高32位和低32位,用32位乘法模拟64位乘法,手动计算出低64位结果,完全符合C标准:

#include <stdint.h>

void imull(int64_t a, int64_t b, int64_t *res) {
    // 将两个64位整数拆分为高32位和低32位(用无符号类型避免符号扩展问题)
    uint32_t a_high = (uint32_t)(a >> 32);
    uint32_t a_low = (uint32_t)a;
    uint32_t b_high = (uint32_t)(b >> 32);
    uint32_t b_low = (uint32_t)b;

    // 计算四个32x32的乘法,每个结果都是64位(对应展开后的四个项)
    uint64_t mul_low_low = (uint64_t)a_low * b_low;
    uint64_t mul_low_high = (uint64_t)a_low * b_high;
    uint64_t mul_high_low = (uint64_t)a_high * b_low;
    // mul_high_high只会影响结果的高64位,这里我们不需要管它

    // 计算低64位:mul_low_low的全部64位 + mul_low_high的低32位左移32 + mul_high_low的低32位左移32
    uint64_t total_low = mul_low_low + ((mul_low_high & 0xFFFFFFFFULL) << 32) + ((mul_high_low & 0xFFFFFFFFULL) << 32);

    // 把无符号的64位结果转成int64_t,就是我们要的低64位
    *res = (int64_t)total_low;
}

代码逻辑说明

  • 拆分整数:用uint32_t来存拆分后的高/低32位,这样做乘法的时候不会因为符号位扩展导致错误。
  • 分步乘法:把a*b展开成(a_high*2^32 + a_low)*(b_high*2^32 + b_low),四个乘法项里,只有前三个会影响低64位,第四个a_high*b_high的结果只会出现在高64位,所以我们可以忽略它。
  • 合并结果:把三个影响低64位的项加起来,就得到了最终的低64位结果——这里的加法即使有进位也没关系,因为我们只需要低64位,进位会自动被截断(或者说,进位本来就是高64位的部分,我们不需要)。

额外提示

如果你只是图省事,在大多数编译器(比如GCC、Clang、MSVC)上直接写*res = a * b;也能得到正确的低64位结果,但因为C标准明确规定有符号整数溢出是未定义行为,所以这种写法在严格场景下不推荐。上面的拆分方法是完全可移植的,不管什么平台什么编译器都能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 09:42:45