我在C中工作,需要添加和减去64位数字和128位数字。结果将保存在128位数字中。我使用整数数组来存储128位数字的上半部分和下半部分(即uint64_t bigNum[2]
,其中bigNum[0]
是最不重要的。)
任何人都可以帮助使用加法和减法函数,该函数可以接受bigNum并为其添加/减去uint64_t
吗?
我在网上看到了很多不正确的例子,请考虑一下:
bigNum[0] = 0;
bigNum[1] = 1;
subtract(&bigNum, 1);
此时bigNum[0]
应设置所有位,而bigNum[1]
不应设置位。
答案 0 :(得分:2)
在1年级或2年级,你应该学会如何将1和10分成几部分,通过将它分成几个单位和单位的多个单独添加。处理大数时,相同的原理可以应用于计算任意大数的算术运算,通过实现你的单位现在是2 ^位的单位,你的“十位”大2 ^位等等。
答案 1 :(得分:1)
这适用于减法:
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;
}
增加非常相似。当然,上述内容也可以通过明确的测试来表达,但我发现总是借用它会更清晰。优化留作练习。
对于等于bigNum
的{{1}},减去2将使其等于{ 0, 1 }
,这是表示-1的正确位模式。这里,假设UL将整数提升到64位,当然这取决于编译器。
答案 2 :(得分:0)
对于您减去的值小于或等于bignum[0]
的情况,您不必触摸bignum[1]
。
如果不是,则无论如何都会从bignum[0]
中减去它。此操作将环绕,但这是您需要的行为。此外,您必须从bignum[1]
中删除1。
答案 3 :(得分:0)
大多数编译器本质上支持__int128类型。
尝试一下,你可能会很幸运。
答案 4 :(得分:0)
在许多架构中,添加/减去任意长整数非常容易,因为有一个进位标志和带有标志指令的add / sub。例如,在x86 rdx:rax += r8:r9
上就可以这样做
add rax, r9
adc rdx, r8
在C中,无法访问此进位标志,因此您必须自己计算该标志。最简单的方法是检查无符号和是否小于操作数like this。例如要做a += b
,我们会这样做
aL += bL;
aH += bH + (aL < bL);