对于较大的 值n,需要大格式。
由于您不能使用乘法,因此您必须自己实现它似乎是合乎逻辑的。
实际上,由于只需要添加,因此如果我们不寻求高效率,则实施起来并不困难。
无论如何都有一点困难:您必须将输入整数转换为数字数组。由于我猜不允许模数,我在snprintf函数的帮助下实现了它。
结果:
100! is 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
注意:此结果是即时提供的。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NDIGITS 1000 // maximum number of digits
struct MyBig {
int digits[NDIGITS + 2]; // "+2" to ease overflow control
int degree;
};
void reset (struct MyBig *big) {
big->degree = 0;
for (int i = 0; i <= NDIGITS; ++i) big->digits[i] = 0;
}
void create_with_div (struct MyBig *big, int n) { // not used here
reset (big);
while (n != 0) {
big->digits[big->degree++] = n%10;
n /= 10;
}
if (big->degree != 0) big->degree--;
}
void create (struct MyBig *big, int n) {
const int ND = 21;
char dig[ND];
snprintf (dig, ND, "%d", n);
int length = strlen (dig);
reset (big);
big->degree = length - 1;
for (int i = 0; i < length; i++) {
big->digits[i] = dig[length - 1 - i] - '0';
}
}
void print (struct MyBig *big) {
for (int i = big->degree; i >= 0; --i) {
printf ("%d", big->digits[i]);
}
}
void accumul (struct MyBig *a, struct MyBig *b) {
int carry_out = 0;
for (int i = 0; i <= b->degree; ++i) {
int sum = carry_out + a->digits[i] + b->digits[i];
if (sum >= 10) {
carry_out = 1;
a->digits[i] = sum - 10;
} else {
carry_out = 0;
a->digits[i] = sum;
}
}
int degree = b->degree;
while (carry_out != 0) {
degree++;
int sum = carry_out + a->digits[degree];
carry_out = sum/10;
a->digits[degree] = sum % 10;
}
if (a->degree < degree) a->degree = degree;
if (degree > NDIGITS) {
printf ("OVERFLOW!!\n");
exit (1);
}
}
void copy (struct MyBig *a, struct MyBig *b) {
reset (a);
a->degree = b->degree;
for (int i = 0; i <= a->degree; ++i) {
a->digits[i] = b->digits[i];
}
}
void fact_big (struct MyBig *ans, unsigned int num) {
create (ans, 1);
int temp = 1;
while (temp <= num){
int ctr = 0;
struct MyBig temp2;
reset (&temp2);
while (ctr != temp){
accumul (&temp2, ans);
ctr ++;
}
copy (ans, &temp2);
temp ++;
}
return;
}
unsigned long long int fact (unsigned int num) {
unsigned long long int ans = 1;
int temp = 1;
while (temp <= num){
int ctr = 0;
unsigned long long int temp2 = 0;
while (ctr != temp){
temp2 += ans;
ctr ++;
}
ans = temp2;
temp ++;
}
return ans;
}
void main(){
unsigned long long int ans;
unsigned int num;
printf("Enter a number: ");
scanf("%u", &num);
ans = fact (num);
printf("%u! is %llu\n", num, ans);
struct MyBig fact;
fact_big (&fact, num);
printf("%u! is ", num);
print (&fact);
printf ("\n");
}