我正在尝试计算100!(即100的阶乘)。
我正在寻找使用C语言完成这个任务最简单的方法。我查阅了一些资料,但没有找到确切的答案。
如果您需要知道,我在Mac OS X中使用Xcode编程。
我正在尝试计算100!(即100的阶乘)。
我正在寻找使用C语言完成这个任务最简单的方法。我查阅了一些资料,但没有找到确切的答案。
如果您需要知道,我在Mac OS X中使用Xcode编程。
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位平台上想使用uint64_t
作为大整数数组),那么将底数设为更小的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');
希望这可以帮到你!我将其他的实现(例如两个大整数的加法,乘法等)留给你作为练习。只需回想起在小学时如何学习使用基数10进行加法、乘法、除法等,并教计算机以相同方式进行操作(但使用基数10^9或基数2^32),你应该不会遇到问题。如果你愿意使用一个库的实现,标准的实现似乎是GMP
mpz_t out;
mpz_init(out);
mpz_fac_ui(out,100);
mpz_out_str(stdout,10,out);
应该通过查看文档计算100!
您希望知道最简单的方法来完成这件事。所以,这里有:
#include <gmp.h>
#include <stdio.h>
int main(int argc, char** argv) {
mpz_t mynum;
mpz_init(mynum);
mpz_add_ui(mynum, 100);
int i;
for (i = 99; i > 1; i--) {
mpz_mul_si(mynum, mynum, (long)i);
}
mpz_out_str(stdout, 10, mynum);
return 0;
}
我测试了这段代码,它给出了正确的答案。
<stdio.h>
和char类型就可以在C语言中打印出1000的阶乘:#include <stdio.h>
#define B_SIZE 3000 // number of buffered digits
struct buffer {
size_t index;
char data[B_SIZE];
};
void init_buffer(struct buffer *buffer, int n) {
for (buffer->index = B_SIZE; n; buffer->data[--buffer->index] = (char) (n % 10), n /= 10);
}
void print_buffer(const struct buffer *buffer) {
for (size_t i = buffer->index; i < B_SIZE; ++i) putchar('0' + buffer->data[i]);
}
void natural_mul_buffer(struct buffer *buffer, const int n) {
int a, b = 0;
for (size_t i = (B_SIZE - 1); i >= buffer->index; --i) {
a = n * buffer->data[i] + b;
buffer->data[i] = (char) (a % 10);
b = a / 10;
}
for (; b; buffer->data[--buffer->index] = (char) (b % 10), b /= 10);
}
int main() {
struct buffer number_1 = {0};
init_buffer(&number_1, 1);
for (int i = 2; i <= 100; ++i)
natural_mul_buffer(&number_1, i);
print_buffer(&number_1);
}
你会发现计算 "小" 的 factorial(10000)
的速度更快,几乎是瞬间完成的。
你可以将它放入一个 fact.c
文件中,然后编译+执行:
gcc -O3 -std=c99 -Wall -pedantic fact.c ; ./a.out ;