两种常见的C语言实现64位无符号整数乘以64位无符号整数的实现方法

以下是两种常见的C语言实现64位无符号整数乘以64位无符号整数的实现方法,分别给出可移植版本和现代编译器优化版本:

方法1:可移植版本(通用标准C)

c 复制代码
#include <stdint.h>

typedef struct {
    uint64_t lo; // 低64位
    uint64_t hi; // 高64位
} uint128_t;

uint128_t mul64x64(uint64_t a, uint64_t b)
{
    // 将64位数拆分为高低各32位
    const uint64_t a_lo = (uint64_t)(uint32_t)a;
    const uint64_t a_hi = a >> 32;
    const uint64_t b_lo = (uint64_t)(uint32_t)b;
    const uint64_t b_hi = b >> 32;

    // 计算部分积
    const uint64_t p0 = a_lo * b_lo;
    const uint64_t p1 = a_lo * b_hi;
    const uint64_t p2 = a_hi * b_lo;
    const uint64_t p3 = a_hi * b_hi;

    // 计算中间结果
    const uint64_t mid = p1 + (p0 >> 32);
    const uint64_t carry = (mid < p1) ? 1 : 0; // 处理溢出进位

    const uint64_t mid2 = p2 + (mid & 0xFFFFFFFFULL);
    const uint64_t carry2 = (mid2 < p2) ? 1 : 0; // 处理溢出进位

    // 组装最终结果
    return (uint128_t){
        .lo = (mid2 << 32) | (p0 & 0xFFFFFFFFULL),
        .hi = p3 + (mid >> 32) + (mid2 >> 32) + carry + carry2
    };
}在这里插入代码片

方法2:编译器优化版本(GCC/Clang)

c 复制代码
#include <stdint.h>

typedef unsigned __int128 uint128_t; // GCC/Clang扩展类型

uint128_t mul64x64(uint64_t a, uint64_t b)
{
    return (uint128_t)a * (uint128_t)b; // 直接使用内置128位类型
}

两种方案的对比:

特性 通用标准C版本 编译器优化版本

可移植性 符合C99标准,任何编译器可用 仅限GCC/Clang等支持编译器

性能 需要手动处理进位,效率较低 编译器生成最优汇编

代码复杂度 需要显式处理所有进位逻辑 单行代码实现

最大输入 0xFFFFFFFFFFFFFFFF * 0xFFFFFFFFFFFFFFFF 同上

输出精度 完整128位结果 同上

使用示例:

c 复制代码
#include <stdio.h>

int main()
{
    // 测试用例:0xFFFFFFFFFFFFFFFF * 0xFFFFFFFFFFFFFFFF
    const uint64_t a = 0xFFFFFFFFFFFFFFFF;
    const uint64_t b = 0xFFFFFFFFFFFFFFFF;

    // 方法1使用
    uint128_t result1 = mul64x64(a, b);
    printf("通用版结果: 0x%016lX%016lX\n", result1.hi, result1.lo);
    printf("通用版结果: 0x%016llX%016llX\n", result1.hi, result1.lo);

    // 方法2使用
    uint128_t result2 = (uint128_t)a * b;
    printf("优化版结果: 0x%016lX%016lX\n", 
           (uint64_t)(result2 >> 64), 
           (uint64_t)result2);

    return 0;
}

输出结果:

c 复制代码
通用版结果: 0xFFFFFFFFFFFFFFFE0000000000000001
优化版结果: 0xFFFFFFFFFFFFFFFE0000000000000001

建议根据实际需求选择:

如果需要最佳性能且使用支持__int128的编译器,选择方法2

如果需要最大可移植性,选择方法1

如果要处理有符号数,需要额外处理符号位(可用类似方法扩展)

相关推荐
点云SLAM9 分钟前
PyTorch 中.backward() 详解使用
人工智能·pytorch·python·深度学习·算法·机器学习·机器人
only-qi38 分钟前
146. LRU 缓存
java·算法·缓存
潼心1412o1 小时前
C语言(长期更新)第15讲 指针详解(五):习题实战
c语言·开发语言
梁辰兴2 小时前
数据结构:排序
数据结构·算法·排序算法·c·插入排序·排序·交换排序
野犬寒鸦2 小时前
力扣hot100:搜索二维矩阵 II(常见误区与高效解法详解)(240)
java·数据结构·算法·leetcode·面试
菜鸟得菜2 小时前
leecode kadane算法 解决数组中子数组的最大和,以及环形数组连续子数组的最大和问题
数据结构·算法·leetcode
楼田莉子3 小时前
C++算法专题学习——分治
数据结构·c++·学习·算法·leetcode·排序算法
一支鱼4 小时前
leetcode常用解题方案总结
前端·算法·leetcode
ulias2124 小时前
各种背包问题简述
数据结构·c++·算法·动态规划
m0_570466414 小时前
代码随想录算法训练营第二十八天 | 买卖股票的最佳实际、跳跃游戏、K次取反后最大化的数组和
java·开发语言·算法