使用 32 位无符号整数乘以 64 位数字的算法

Posted

技术标签:

【中文标题】使用 32 位无符号整数乘以 64 位数字的算法【英文标题】:Algorithm to multiply 64-bit numbers using 32-bit unsigned integers 【发布时间】:2011-09-27 13:31:16 【问题描述】:

我有 64 位数字(63 位 + 符号位),表示为二进制补码,存储在两个无符号 32 位整数中。

struct Long

    uint32 high;
    uint32 low;

如何实现一个乘法算法,只使用 32 位数字,并检查结果是否适合 63 位?如果结果不合适,我想返回一个指示溢出的错误代码。

【问题讨论】:

大多数编译器都有一个 long long 类型,它是 64 位,应该使用乘法。 我需要算法,假设不支持 64 位。 ***描述了计算机使用的算法:en.wikipedia.org/wiki/Multiplication_algorithm 另见en.wikipedia.org/wiki/Binary_multiplier 你应该问这个很有趣,我今天一直在实现这个算法。我正在使用内联汇编程序(in g++ for Intel IA-32),这可能不适合您——您的操作系统和编译器是什么? 【参考方案1】:

一般你需要 2*n 位来存储两个 n 位数字的乘积(最大的结果是 (2^n)^2 = 2^(2*n)),所以我最好的想法是把数字分开分成四个 16 位部分,将它们一一相乘,然后相加。总共有 16 次乘法,但错误检查是微不足道的。

【讨论】:

错误检查可能很简单,但我怀疑维护进位会有点复杂。 应该是可行的。必须检查乘法的低部分是否溢出并将其带入高部分,但这无论如何都无法避免。 确保将变量更改为正数并进行无符号乘法,然后在完成后将其更改为有符号。【参考方案2】:

查看GNU MP library 中的“longlong.h”头文件。我相信这个头文件的一个版本也在 GNU C 源代码中。宏:smul_ppmm 根据无符号双字积定义:umul_ppmm。这为您提供了 32x32=>64 位乘法,您可以使用它来实现 64x64=>128 位乘法。

【讨论】:

以上是关于使用 32 位无符号整数乘以 64 位数字的算法的主要内容,如果未能解决你的问题,请参考以下文章

Shopee 一面算法题:颠倒给定的 32 位无符号整数

在 32 位 iPhone 上处理 64 位整数

如何在 AVX2 中将 32 位无符号整数转换为 16 位无符号整数?

如何从 32 位 R 整数中提取 4 位无符号整数?

如何在 C 中提取 32 位无符号整数的特定“n”位?

如何将两个32位整数组合成一个64位整数?