没有进位标志的大整数加法

fre*_*low 3 c c++ addition arbitrary-precision carryflag

在汇编语言中,通常有一条指令可以添加两个操作数和一个进位.如果要实现大整数加法,只需添加最小的整数而不带进位,将下一个整数与进位相加.如何在C或C++中有效地执行此操作,而我无法访问进位标志?它应该适用于几个编译器和体系结构,所以我不能简单地使用内联汇编等.

小智 5

你可以使用"nail"(来自GMP的术语):而不是uint64_t在表示数字时使用a的所有64位,而只使用其中的63位,顶部位为零.这样,您可以通过简单的位移检测溢出.你甚至可能想要少于63.

或者,你可以做半字算术.如果可以执行64位运算,则将数字表示为uint32_ts 的数组(或者等效地将64位字拆分为上下32位块).然后,当对这些32位整数进行算术运算时,你可以先将64位进行算术运算,然后再转换回来.这使您可以检测进位,如果您没有"乘法运算"指令,它也适合乘法运算.

正如另一个答案所示,您可以通过以下方式检测无符号加法中的溢出:

uint64_t sum = a + b;
uint64_t carry = sum < a;
Run Code Online (Sandbox Code Playgroud)

顺便说一句,虽然在实践中这也适用于签名算术,但你有两个问题:

  • 它更复杂
  • 从技术上讲,溢出有符号整数是未定义的行为

所以你最好坚持使用无符号数字.