如果您正在寻找一个简单的库,libtommath(来自 libtomcrypt)可能是您想要的。
如果您希望自己编写一个简单的实现(作为学习练习,或者因为您只需要非常有限的 bigint 功能子集,并且不想依赖于大型库,命名空间污染,等),那么我可能会针对您的问题提出以下建议:
由于您可以根据n 限制结果的大小,因此只需预先分配一个具有所需大小的uint32_t 数组来保存结果。我猜你会想要打印结果,所以使用10的幂(即1000000000)而不是2的幂是有意义的。也就是说,数组的每个元素都可以包含 0 到 999999999 之间的值。
要将此数字乘以(正常、非大)整数 n,请执行以下操作:
uint32_t carry=0;
for(i=0; i<len; i++) {
uint64_t tmp = n*(uint64_t)big[i] + carry;
big[i] = tmp % 1000000000;
carry = tmp / 1000000000;
}
if (carry) big[len++] = carry;
如果您知道n 永远不会大于 100(或其他一些小数字)并且想要避免进入 64 位范围(或者如果您在 64 位平台上并且想要使用 @ 987654326@ 用于您的 bigint 数组),然后将基数设为 10 的较小幂,以便乘法结果始终适合类型。
现在,打印结果就像这样:
printf("%lu", (long)big[len-1]);
for(i=len-1; i; i--) printf("%.9lu", (long)big[i-1]);
putchar('\n');
如果你想使用 2 的幂作为底数,而不是 10 的幂,那么乘法会变得更快:
uint32_t carry=0;
for(i=0; i<len; i++) {
uint64_t tmp = n*(uint64_t)big[i] + carry;
big[i] = tmp;
carry = tmp >> 32;
}
if (carry) big[len++] = carry;
但是,以十进制打印结果并不那么令人愉快... :-) 当然,如果您想要十六进制的结果,那很容易:
printf("%lx", (long)big[len-1]);
for(i=len-1; i; i--) printf("%.8lx", (long)big[i-1]);
putchar('\n');
希望这会有所帮助!我将把实现其他东西(如加法、2 个 bigint 的乘法等)作为练习留给你。回想一下您在小学时如何学习以 10 为底的加法、乘法、除法等,并教计算机如何做到这一点(但改为以 10 ^ 9 或 2 ^ 32 为底),您应该没问题。