首页 >后端开发 >C++ >如何在 C 中提取 64 位整数乘法的高位部分?

如何在 C 中提取 64 位整数乘法的高位部分?

Patricia Arquette
Patricia Arquette原创
2024-11-14 09:38:02444浏览

How to Extract the Higher Part of 64-bit Integer Multiplication in C  ?

Extracting the High Part of 64-bit Integer Multiplication

In C , multiplying two 64-bit integers ( uint64_t ) results in a value representing the lower 64 bits of the product. This operation is commonly used to achieve modular arithmetic, where the lower bits contain the desired remainder. However,有时候,我们也需要计算乘法的更高位部分。

最优方案

考虑以下场景:

uint64_t i = // some value
uint64_t j = // some value
uint64_t k = mulhi(i, j); // where mulhi() returns the higher part of the 64-bit multiplication

如果使用支持 128 位数字的 GCC 编译器,最有效的策略是执行 128 位乘法并提取高 64 位。

无 128 位支持时的替代方案

如果没有 128 位支持,可以使用 Yakk 提供的方法。这个方法将 ab 各分解为两个 32 位数字,然后使用 64 位乘法分别计算这些较小数字的乘积。

分解如下:

uint64_t a_lo = (uint32_t)a;
uint64_t a_hi = a >> 32;
uint64_t b_lo = (uint32_t)b;
uint64_t b_hi = b >> 32;

现在,乘积可以表示为:

a * b = ((a_hi << 32) + a_lo) * ((b_hi << 32) + b_lo)

      = ((a_hi * b_hi) << 64) +
        ((a_hi * b_lo) << 32) +
        ((b_hi * a_lo) << 32) +
          a_lo * b_lo

但是,使用 64 位对上述公式进行计算会产生溢出。因此,我们需要对中间结果进行特殊处理:

// 为防止溢出而引入的临时变量
uint64_t a_x_b_hi = a_hi * b_hi;
uint64_t a_x_b_mid = a_hi * b_lo;
uint64_t b_x_a_mid = b_hi * a_lo;
uint64_t a_x_b_lo = a_lo * b_lo;

// 计算进位位
uint64_t carry_bit = (((uint64_t)(uint32_t)a_x_b_mid +
                         (uint64_t)(uint32_t)b_x_a_mid +
                         (a_x_b_lo >> 32)) >> 32);

// 计算高位部分并返回
uint64_t multhi = a_x_b_hi +
                     (a_x_b_mid >> 32) + (b_x_a_mid >> 32) +
                     carry_bit;

return multhi;

稍做修改,如果不在意高位部分多 1,则可以省略进位位的计算。

以上是如何在 C 中提取 64 位整数乘法的高位部分?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn