在很多C/C++的书上,都给出了两种阶乘的计算方法,一种为利用递归进行计算;一种利用阶乘的定义进行计算。下面给出这两种算法的C程序源代码。
1. 利用阶乘的定义进行计算:
1: unsigned long factorial( int n )2: {3: if( n == 0 )
4: return 1;
5: unsigned long result = 1;6: for( int i = 1; i < n + 1; ++i )7: {8: result *= i;9: }10: return result;
11: }2. 利用递归进行计算:
1: unsigned long factorial( unsigned long n )2: {3: unsigned long result = 0;4: if( n == 0 )
5: return 1;
6: else
7: result = n*factorial( n-1 );8: return result;
9: }
但是,由于阶乘的结果随着n的增大将急剧增加。最终导致即使是unsigned long类型的整数也无法保存计算结果。那么,这时候,我们应该怎么办呢?
现在,我们就要介绍一种计算方法,该方法的主要思路如下:
1.开辟一个大小为10000或更大的整形数组;
2.数组的每一个元素只保存计算结果中的一位数字,数组索引最小的元素对应计算结果的最小位,依次类推;
3.在计算中,将1-n中的每一个数字都与数组中的每一个数相乘,将与某元素的乘积仍保存在该元素中;
4.在1-n中的每个数字与所有元素做完乘积之后,依次每一个元素中的数字是否超过10(或者radix),若超过,则向前进位;
按照上面所描述的算法,我们在这里利用C++语言进行了实现:
1: #include <iostream>2: #include <sstream>3:4: #define s_int short int5: #define MAXDIGIT 500006: #define RADIX 107:8: using std::cout;
9: using std::endl;
10: using std::cin;
11:12: //实现进位
13: bool carry( s_int result[], int &dgts )14: {15: int i;
16: s_int carry_value = 0;17: for( i = 0; i < dgts; i++ )
18: {19: result[i] += carry_value;20: carry_value = ( result[i] < RADIX ) ? 0 : ( result[i] / RADIX );21: result[i] -= carry_value * RADIX;22: }23:24: //处理最后一位:
25: //若需进位,则循环进位,直到不需进位为止
26: result[i] += carry_value;27: while( result[i] >= RADIX && i < MAXDIGIT )
28: {29: carry_value = result[i] / RADIX;30: result[i] -= carry_value * RADIX;31: result[++i] = carry_value;32: ++dgts;33: }34:35: if( i >= MAXDIGIT )
36: return false;37:38: return true;39: }40:41: //
42: // The function return the total digits of the result.
43: //
44: int factorial( int n, s_int result[] )45: {46: memset(result, 0, sizeof(s_int)*MAXDIGIT);
47: int digits = 0;
48: result[0] = 1;49:50: // 0! = 1
51: if( n == 0 ) return 1;52:53: for( int i = 2; i < n+1; ++i )54: {55: for( int j = 0; j <= digits; ++j )56: {57: result[j] *= i;58: }59: if( !carry( result, digits ) )
60: break;
61: }62:63: return digits >= MAXDIGIT ? -1 : digits;
64: }65:66: void print( s_int result[], const int &digits )67: {68: if( digits < 10 )
69: for( int i = digits; i >= 0; i-- )70: cout << result[i];71: else
72: {73: cout << result[digits] <<".";
74: for( int i = digits -1; i >= 0; i-- )75: cout << result[i];76: cout << "E" << digits;
77: }78: cout << endl;79: }80:81: int main(void)82: {83: s_int result[MAXDIGIT];84: int n;
85: int digits;
86:87: cout << "Input the value of n: ";
88: cin >> n;89:90: if( n < 0 )
91: {92: cout << "Error: A positive integer is need!" << endl;
93: return 0;
94: }95:96: if( (digits = factorial(n, result)) == -1 )
97: {98: cout << "Error: Overflow!" << endl;
99: return 0;
100: }101: else
102: {103: print(result, digits);104: return 0;
105: }106: }
对1000!进行计算,计算结果如图: