仅使用 32 位整数的算术运算

Posted

技术标签:

【中文标题】仅使用 32 位整数的算术运算【英文标题】:Arithmetic Operations using only 32 bit integers 【发布时间】:2015-03-07 00:58:11 【问题描述】:

在只能乘以 32 位数的微处理器上,您将如何计算两个 1024 位数的乘法?

【问题讨论】:

您有特定的语言吗?如果您使用的是 Java,请查看 java.math 包中的 BigInteger 类。如果没有,请为您正在使用的内容查找类似的库。 示例代码:sites.google.com/site/indy256/algo_cpp/bigint 不,我对它背后的数学感兴趣,不一定是实现细节。 然后阅读 Karatsuba 算法:en.wikipedia.org/wiki/Karatsuba_algorithm。或者只是从你在小学教过的算法中概括出来,用代表 10 个可能数字的“单词”进行长乘法:-) 像手动一样乘法。算法基本相同...使用base 2^32。 【参考方案1】:

首先要意识到您已经知道如何做到这一点:在小学时,您被教导如何对一位数进行算术运算,然后给出数据结构来表示更大的数字(例如小数)和计算算法算术运算(例如长除法)。

如果您有办法将两个 32 位数字相乘得到 64 位结果(请注意,unsigned long long 保证至少为 64 位),那么您可以使用这些相同的算法在基数中进行算术运算2^32。

您还需要,例如,带有进位的加法运算。您可以通过检测溢出来确定两个相同类型的无符号数相加时的进位,例如如下:

uint32_t x, y; // set to some value
uint32_t sum = x + y;
uint32_t carry = (sum < x);

(从技术上讲,这种操作要求您执行无符号算术:有符号算术中的溢出是未定义的行为,优化器会对您的代码做出您最意想不到的事情)

(现代处理器通常提供将两个 64 位数字相乘得到 128 位结果的方法,但要访问它,您必须使用 128 位类型之类的编译器扩展,或者您必须内联编写汇编代码。现代处理器也有专门的 add-with-carry 指令)

现在,高效地进行算术是一项巨大的工程;我发现浏览文档和源代码到gmp,GNU 多精度算术库非常有启发性。

【讨论】:

【参考方案2】:

    查看 bigint 操作的任何实现

    这是我在 C++ 中为fast bignum square 使用的一些方法 有些仅用于 sqr,但有些可用于乘法...

    使用 32 位算术作为 64/128/256/...位算术的模块

    见我的32bit ALU in x86 C++ 使用带数字基数的长乘法2^32 这种方式也可以使用 Karatsuba

【讨论】:

以上是关于仅使用 32 位整数的算术运算的主要内容,如果未能解决你的问题,请参考以下文章

PHP中任意大整数的算术运算

C 指针的算术运算

C 指针的算术运算

numpy ufunc/算术性能 - 整数不使用 SSE?

如何在恒定时间内仅使用算术运算计算指数?

8 位和 16 位整数的算术运算