这是一个小程序,用于确定在unsigned long long 中的最大阶乘数:
#include <limits.h>
#include <stdio.h>
int main(void) {
unsigned long long int i, factorial;
for (i = factorial = 1; factorial <= ULLONG_MAX / i; i++) {
factorial = factorial * i;
}
printf("\nMaximum number is: %llu! = %llu\n", i - 1, factorial);
return 0;
}
输出:Maximum number is: 20! = 2432902008176640000
除此之外,如果您的系统上可用,您可以使用更大的整数类型:
#include <stdio.h>
char *int128toa(char *dest, __uint128_t n) {
int i = 0, j = 0;
do {
dest[i++] = '0' + (n % 10);
} while (n /= 10);
dest[i] = '\0';
while (i --> j) {
char c = dest[i];
dest[i] = dest[j];
dest[j++] = c;
}
return dest;
}
int main(void) {
char buf1[sizeof(__uint128_t) * 4];
char buf2[sizeof(__uint128_t) * 4];
__uint128_t i, factorial, uint128_max = ~(__uint128_t)0;
for (i = factorial = 1; factorial <= uint128_max / i; i++) {
factorial = factorial * i;
}
printf("\nMaximum number is: %s! = %s\n",
int128toa(buf1, i - 1), int128toa(buf2, factorial));
return 0;
}
输出:Maximum number is: 34! = 295232799039604140847618609643520000000
这仍然是一个很小的数字。阶乘呈指数增长。
对于较大的数字,您将使用 bignum 包,其中数字在分配的数组中表示,其大小仅受可用内存限制。广泛可用的一个是 GNU 多精度包 gmp.h。
这是一个计算存储为字符串的较大阶乘的简单程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *strrev(char *s) {
size_t j = 0, i = strlen(s);
while (i --> j) {
char c = s[i];
s[i] = s[j];
s[j++] = c;
}
return s;
}
char *mulstr(char *s, int n) {
size_t i = 0;
int carry = 0;
while (s[i]) {
carry += n * (s[i] - '0');
s[i++] = '0' + carry % 10;
carry /= 10;
}
while (carry) {
s = realloc(s, i + 2);
s[i++] = '0' + carry % 10;
carry /= 10;
}
s[i] = '\0';
return s;
}
char *factorial(int n) {
char *f = strdup("1");
for (int i = 2; i <= n; i++) {
f = mulstr(f, i);
}
return f;
}
int main() {
int n = 100;
char *p = factorial(n);
printf("%d! = %s\n", n, strrev(p));
free(p);
return 0;
}
输出:
100! 4.