我想要计算100!
我正在寻找使用C来实现这一目标的最简单方法.我已阅读但未找到具体答案.
如果你必须知道,我在Mac OS X中用Xcode编程.
谢谢!
R..*_*R.. 23
如果您正在寻找一个简单的库,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;
Run Code Online (Sandbox Code Playgroud)
如果你知道n永远不会超过100(或其他一些小数字)并且想要避免进入64位范围(或者如果你在64位平台上并且想要uint64_t用于你的bigint数组),那么使基数小于10的幂,以便乘法结果始终适合该类型.
现在,打印结果就像:
printf("%lu", (long)big[len-1]);
for(i=len-1; i; i--) printf("%.9lu", (long)big[i-1]);
putchar('\n');
Run Code Online (Sandbox Code Playgroud)
如果你想使用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;
Run Code Online (Sandbox Code Playgroud)
但是,以十进制打印结果将不会那么令人愉快... :-)当然,如果您希望结果为十六进制,那么很容易:
printf("%lx", (long)big[len-1]);
for(i=len-1; i; i--) printf("%.8lx", (long)big[i-1]);
putchar('\n');
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!我会留下实施其他东西(比如加法,乘以2个bigint等)作为练习.回想一下你是如何在小学阶段学习基础10加法,乘法,除法等的,并教电脑如何做到这一点(但在基数-10 ^ 9或基数-2 ^ 32而不是)你应该没问题.
如果您愿意使用库实现,那么标准实现似乎是GMP
mpz_t out;
mpz_init(out);
mpz_fac_ui(out,100);
mpz_out_str(stdout,10,out);
Run Code Online (Sandbox Code Playgroud)
应该算100!从查看文档.