如何正确添加/减去128位数字(如两个u_int64_t)

我在C中工作,需要添加和减去64位数字和128位数字。 结果将保存在128位数字中。 我使用整数数组来存储128位数的上半部和下半部(即u_int64_t bigNum[2] ,其中bigNum[0]是最不重要的)。

任何人都可以帮助添加和减法函数,可以接受bigNum并添加/减去u_int64_t吗?

我在网上看到了很多不正确的例子,所以请考虑一下:

 bigNum[0] = 0; bigNum[1] = 1; subtract(&bigNum, 1); 

此时bigNum[0]应该设置所有位,而bigNum[1]应该没有设置位。

在1年级或2年级,你应该学会如何将1和10的加法分解成几部分,将它分成几个单位和单位的多个单独添加。 处理大数时,相同的原理可以应用于计算任意大数的算术运算,通过实现你的单位现在是2 ^位的单位,你的“十”是2 ^位更大,依此类推。

这适用于减法:

 typedef u_int64_t bigNum[2]; void subtract(bigNum *a, u_int64_t b) { const u_int64_t borrow = b > a[1]; a[1] -= b; a[0] -= borrow; } 

增加非常相似。 当然,上面的内容也可以用明确的测试来表达,但我发现总是借用它会更清晰。 优化留作练习。

对于等于{ 0, 1 }bigNum ,减去2会使它等于{ ~0UL, ~0UL } ,这是表示-1的正确位模式。 这里,假设UL将整数提升到64位,当然这取决于编译器。

对于您减去的值小于或等于bignum[0]您不必触摸bignum[1]

如果不是,你可以从bignum[0]减去它,无论如何。 此操作将环绕,但这是您需要的行为。 此外,你必须从bignum[1]取代1。

大多数编译器本质上支持__int128类型。

尝试一下,你可能会很幸运。

在汇编中,在任意长整数中进行加法/减法非常容易,因为有一个进位标志和带有标志指令的add / sub。

在C中,无法访问此进位标志,因此您必须自己计算该标志。 但这需要很多位操作。 您可以在此处使用更简单的解决方案