在汇编语言中,通常有一条指令可以将两个操作数和一个进位相加。如果你想要实现大整数加法,你只需要将最低位的整数不带进位相加,下一个整数带上进位即可。那么,在C或C++中,如何高效地实现这个功能呢?由于没有进位标志,因此不能简单地使用内联汇编等方法。该方法应该能够在多种编译器和架构上工作。
在汇编语言中,通常有一条指令可以将两个操作数和一个进位相加。如果你想要实现大整数加法,你只需要将最低位的整数不带进位相加,下一个整数带上进位即可。那么,在C或C++中,如何高效地实现这个功能呢?由于没有进位标志,因此不能简单地使用内联汇编等方法。该方法应该能够在多种编译器和架构上工作。
uint64_t
的所有64位,而是仅使用其中的63位,并将最高位设置为零。这样,您可以通过简单的位移检测溢出。您甚至可能希望少于63个。uint32_t
数组(或等效地将64位字拆分为上下32位块)。然后,在对这些32位整数进行算术运算时,您可以首先提升到64位,然后在那里执行算术运算,然后转换回来。这使您可以检测进位,并且如果您没有“乘法hi”指令,则对于乘法也很好。uint64_t sum = a + b;
uint64_t carry = sum < a;
顺便提一下,虽然在实践中这也适用于有符号算术,但你会遇到两个问题:
因此,通常最好使用无符号数字。
sum < a
的技巧在 sum = a + b + carry
的情况下是否有效? - fredoverflowa=1
,b=max
,carry=1
。你最终会得到 1
(当然还有一个新的进位),但是 1
并不比 a
小。然而,你可以将其拆分为两个加法。然后,你可以安全地添加这些加法的进位以进行进一步处理,它们在高位字节中最多为2。 - KillianDSa+b
小于a
,那么就会有进位。当然,这是针对正数的a
和b
,但这是你几乎肯定会在bignum库中使用的。carry = 0
for i = 7 to 0:
if a[i] > b[i]:
small = b[i], large = a[i]
else:
small = a[i], large = b[i]
if carry is 1 and large is maxvalue:
c[i] = small
carry = 1
else:
c[i] = large + small + carry
if c[i] < large:
carry = 1
else
carry = 0
for
语句无效。但是Python(或者至少接近它)对于伪代码来说是 _太棒了_,只要你远离那些lambda和map等奇怪的东西 :-) 我实际上使用Python的一个子集来教授基本的编程技能。 - paxdiablob[i]
具有最大值且 carry
为1,则 c[i] == a[i]
。 - user1084944对于无符号类型,您可以通过检查结果是否小于一个操作数(任何一个操作数都可以)来检查进位。
只需从进位0开始即可。
如果我理解得正确的话,您想为自己的大整数类型编写自己的附加程序。
您可以使用一个简单的函数来完成此操作。在第一次运行中不需要担心进位标志。只需从右到左依次相加数字和进位标志(在该函数内部),从进位0开始,并将结果设置为(a+b+carry)%10和进位设置为(a+b+carry)/10。
这个SO可能是相关的: 如何在C语言中实现大整数
unsigned x[8];
。 - fredoverflowuintN_t
类型(例如uint32_t
)。 - user1084944uint256_t
。 - Puppy