阶乘的计算

来源:互联网 发布:floyd算法复杂度 编辑:程序博客网 时间:2024/05/02 23:58

最近看到一条题目,计算n!,阶乘由于它的特殊性,需要涉及到大数运算,本文在32位机器下描述一个简单的计算方法。

        网上有很多种方法,本文就用数组的形式来保存计算结果,首先可以知道unsigned的数据范围是0-2^32-1,因此常规的想法就是将进制提升到2^32,从而用一个数组来保存计算结果,下面给出具体代码:

int bigNum( int x, unsigned *p, int len ){if ( 13 > x || p == NULL || len <= 0 )return -1;p[0] = 479001600;int c = 1;__int64 base = 0x100000000;for ( int i=13; i<=x; i++ ){int addbit = 0;__int64 num = 0;for ( int j=0; j<c; j++ ){num = p[j];num = num*i + addbit;if ( num <= base-1 ){p[j] = (unsigned)num;addbit = 0;}else{p[j] = num%base;addbit = num/base;}}if ( addbit != 0 )p[c++] = addbit;}return c;}
首先,根据计算可知,12!=479001600,没有超过unsigned的范围,上述代码计算13及以上的阶乘,计算过程就是将当前数i依次与结果数组p中的每个数依次相乘,然后加上上一轮的进位,在计算过程中用到了64位num来辅助计算进位,从而防止发生溢出,这个程序本身没有问题,但是调用以后的结果是这样的:

unsigned buf[200] = {0};int c = bigNum( 13, buf, 200 );for(int i=0; i<c; i++)     cout<<buf[i]<<"  ";
输出:

1932053504 1
这样的结果太不直观,可想而知,当计算较大的数的时候,得出的是一堆高低反序,并且以2^32为进制的数组数据,想要直观的输出的十进制数据,貌似好像比较麻烦,我在这里也踌躇了一会儿,转换起来太麻烦,后来仔细一想我可以以2^32为进制,那么同样我也可以以10^x为进制,上述代码我们采用的是unsigned数组来保存最后结果,而unsigned最多可以包含10位10进制数,一次我们可以将进制定为10^9,因此只要将上述代码中的的base修改一下即可:

_int64 base = 1000000000;

然后运行上述测试代码,输出

227020800 6
反过来输出即可得到正确结果6227020800,此处还有需要注意的地方,就是数组中可能省略了前面的0,因此可以将输出部分修改如下:

printf("%d",buf[c-1]);for(int i=c-2;i>=0;i--)     printf("%09d",buf[i]);
需要反序输出,另外出最后一个外,其余需要补齐中间的0

void CalcNN(int n, char *pOut){if ( n <= 0 || pOut == NULL )return;if ( n<=12 ){unsigned num = 1;for ( int i=1; i<=n; i++ )num *= i;sprintf( pOut, "%d", num );return;}unsigned buf[300] = {0};int c = bigNum(n, buf, 300);sprintf( pOut, "%d", buf[c-1] );for ( int i=c-2; i>=0; i-- ){int len = strlen(pOut);sprintf( pOut+len, "%09d", buf[i] );}}
上述代码将最后的结果以字符串的形式保存在pOut所指向的缓存空间中。

       总结:代码本身不复杂,主要的是一个思想,我们可以利用一个较大数据范围类型的数组,来模拟一个较小的进制,本题中base也可以取100、1000........






0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 租房提前退房房东不退押金怎么办 体检时候眼睛有一只是弱视怎么办? b本被扣分9分了怎么办 工作调动后在新单位退休医保怎么办 社保卡和医保卡丢了怎么办 医保卡挂失后又找到了怎么办 医保卡丢失忘了卡号怎么办? 医保卡丢了怎么办又记不住卡号 住院发票丢了医保不给报销怎么办 住院期间被医院丢失了医保卡怎么办 大学时的医保卡毕业后丢了怎么办 用身份证注册的移动卡丢了怎么办 用别人身份证办的卡丢了怎么办 济南医保卡挂失后又找到了怎么办 单位没有给办理医保卡的老人怎么办 单位办的医保卡丢了怎么办 北京退休人员医保卡丢了怎么办 普通发票联丢了医保给报销怎么办 手机买好高铁票身份证丢了怎么办 买了高铁票身份证丢了怎么办 小米手机手电简打开不亮了怎么办 华为p7手机显示屏不亮了怎么办 红米手机3x屏幕不灵怎么办? 乐视1s手机字库坏了怎么办 三星c7手机左右两按钮不亮怎么办 手机摔了一屏碎了下黑屏了怎么办 三星手机摔了一下黑屏了怎么办 行驶证一年扣分超过50分怎么办 朋友去广西传销现在骗我怎么办 行驶证忘带交警查住了怎么办 行驶证正本丢了副本在怎么办 在杭州驾照12分扣完了怎么办 驾照审验期过了40天了怎么办 自己的车借给别人撞死了人怎么办 无证驾驶报别人驾驶证被扣车怎么办 交了强制险但驾驶证过期了怎么办 考驾照科目一身份证掉了怎么办 驾照科目二考试身份证丢了怎么办 身份证遗失又要参加考试怎么办啊 驾驶本到期换本有扣分怎么办 b2驾驶证六年到期有扣分怎么办