void mul(unsigned char a[],unsigned long k,int m,int n) { int i; unsigned long p; unsigned long c=0; for ( i=m+n-1; i>=n;i--) { p= a[i] * k +c; a[i]=(unsigned char)( p % 10); c= p / 10; } while (c>0) { a[i]=(unsigned char)( c % 10); i--; c /=10; } } int main(int argc, char* argv[]) { int i; unsigned char a[]={0,0,0,2,3,4,5}; mul(a,678,4,3); i=0; while ( a[i]==0) i++; for (;i<4+3;i++) printf("%c",a[i]+’0’); //由于数a[i](0<=a[i] <=9)对应的可打印字任符为’0’到’9’,所以显示为i+’0’ return 0; }
从上面的例子可知,在做乘法之前,必须为数组保留足够的空间。具体到计算n!的阶乘时,必须准备一个能容纳的n!的所有位数的数组或者内存块。即数组采有静态分配或者动态分配。前者代码简洁,但只适应于n小于一个固定的值,后者灵活性强,只要有足够的内存,可计算任意n的阶乘,我们这里讨论后一种情况,如何分配一块大小合适的内存。
#include "stdio.h" #include "stdlib.h" #include "memory.h" #include "math.h" #include "malloc.h" void calcFac(unsigned long n) { unsigned long i,j,head,tail; int blkLen=(int)(n*log10((n+1)/2)); //计算n!有数数字的个数 blkLen+=4; //保险起见,多加4位 if (n<=1) { printf("%d!=0/n",n); return;} char *arr=(char *)malloc(blkLen); if (arr==NULL) { printf("alloc memory fail/n"); return ;} memset(arr,0,sizeof(char)*blkLen); head=tail=blkLen-1; arr[tail]=1; for (i=2;i<=n;i++) { unsigned long c=0; for (j=tail;j>=head;j--) { unsigned long prod=arr[j] * i +c; arr[j]=(char)( prod % 10); c= prod / 10; } while (c>0) { head--; arr[head]=(char)(c % 10); c/=10; } } printf("%d!=",n); for (i=head;i<=tail;i++) printf("%c",arr[i]+'0'); printf("/n"); free(arr); } void testCalcFac() { int n; while (1) { printf("n=?"); scanf("%ld",&n); if (n==0) break; calcFac(n); } } int main(int argc, char* argv[]) { testCalcFac(); return 0; }