加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

大数,高精度计算---大数阶乘

发布时间:2020-12-14 03:40:04 所属栏目:大数据 来源:网络整理
导读:大数是算法语言中的数据类型无法表示的数,其位数超过最大数据类型所能表示的范围,所以,在处理大数问题时首先要考虑的是怎样存储大数,然后是在这种存储方式下其处理的实现方法。 一般情况下大数的存储是采用字符数组来存储,即将大数当作一个字符串来存储

大数是算法语言中的数据类型无法表示的数,其位数超过最大数据类型所能表示的范围,所以,在处理大数问题时首先要考虑的是怎样存储大数,然后是在这种存储方式下其处理的实现方法。

一般情况下大数的存储是采用字符数组来存储,即将大数当作一个字符串来存储,而对其处理是按其处理规则在数组中模拟实现。

六??大数阶乘。

?

阶乘问题比较典型,下面,将通过自己的学习逐步介绍。

首先介绍两种常规方法。

?

1.迭代法

[cpp]? view plain copy
  1. ?/*?利用?迭代?来计算整数n的阶乘?*/???
  2. #include?<stdio.h>??
  3. int?main()??
  4. {??
  5. ????int?n;??
  6. ????long?result?=?1;??
  7. ????scanf("%d",&n);??
  8. ????while(?n>1?)??
  9. ????{??
  10. ????????result?*=n;??
  11. ????????n--;??
  12. ????}??
  13. ????printf("%ld",result);??
  14. return?0;??
  15. }??

?

2.递归法

copy
    /*?利用?递归?来计算整数n的阶乘?*/??
  1. long?factorial_recursion(?int?n?)??
  2. ????if(?n<=0?)??
  3. ????{??
  4. ????????return?1;??
  5. else??
  6. return?n?*?factorial_recursion(?n-1?);??
  7. }??
  8. int?main()??
  9. {??
  10. int?n;??
  11. long?result;??
  12. ????scanf("%d",&n);??
  13. ????result?=?factorial_recursion(?n?);??
  14. ????printf("%ld",result);??
  15. return?0;??
  16. }??



这两种方法都比较常规,也比较简单,初学c的时候,还没接触算法,就是利用这样的思路完成。

但是,一旦求N!中N的值大了,那么不管是int 还是 long 都无法满足。这时候就涉及到大数处理的问题上了。

下面介绍常规的大数阶乘。

?

3.利用数组存结果。

copy
    #include?<stdio.h>??
  1. int?a[9000];?//确保保存最终运算结果的数组足够大??
  2. ?????int?digit?=?1;?//位数??
  3. ?????int?temp;???//阶乘的任一元素与临时结果的某位的乘积结果??
  4. int?i,?j,?carry;?//carry:进位??
  5. ??
  6. ?????printf("please?in?put?n:n");??
  7. ????a[0]?=?1;???//将结果先初始化为1??
  8. for?(?i=2;?i<=n;?i++?)??//开始阶乘,阶乘元素从2开始依次"登场"??
  9. ????{??//按最基本的乘法运算思想来考虑,将临时结果的每位与阶乘元素相乘??
  10. ?????????for(?j=1,?carry=0;??j<=digit;?j++?)??
  11. ????????{??
  12. ????????????temp?=?a[j-1]?*?i?+?carry;?//相应阶乘中的一项与当前所得临时结果的某位相乘(加上进位)??
  13. ??????????????a[j-1]?=?temp?%?10;?//更新临时结果的位上信息??
  14. ??????????????carry?=?temp?/?10;?//看是否有进位??
  15. ?????????}??
  16. ????????while(carry)??
  17. ????????{????//如果有进位??
  18. ??????????????a[++digit-1]?=?carry?%?10;?//新加一位,添加信息。位数增1??
  19. ????????????carry?=?carry?/?10;?//看还能不能进位??
  20. ?????????}??
  21. ????}??
  22. ????printf("n?!?=?");????//显示结果??
  23. for(j?=?digit;?j?>=1;j--)??
  24. ????????printf("%d",a[j-1]);??
  25. ????printf("n");??
  26. }??


?

这种大数阶乘算法也比较常规,目前水平能看懂。?

具体思路代码中的注释也比较详细,就不重复了。? 还是模拟笔算的过程。

?

下面附带两个大牛的算法 , 虽然现在还看不懂,但是先mark一下。以后慢慢琢磨。

?

4. 大牛算法一

出处 :??http://www.cnblogs.com/xianghang123/archive/2011/08/24/2152430.html

?

copy
    #define?N?400??
  1. long?a[8916]={1,0},n,i,c,len;???
  2. int?main(void)????
  3. {???
  4. ????n=N;???
  5. for?(?len=1;n>1;?n--)???
  6. ????{???
  7. for?(c=0,i=0;?i<len;i++?)???
  8. ????????{???
  9. ????????????a[i]=?(?c+=?a[i]*n?)?%?10000;?c/=10000;???
  10. ????????}???
  11. ???????????
  12. ????????((a[i]=c)>0)?len++:0;???
  13. ??
  14. ????}??????
  15. for(?len--,printf("%d",a[len--]);len>=0;?len--)?printf("%04d",a[len]);???
  16. ???????????
  17. return?0;???
  18. }??


?

【解释】

?for ( len=1;n>1; n--)???? //把len的长度初始为1,因为数组中已经有一个元素了a[0]=1
?{?
?? for (c=0,i=0; i<len;i++ ) //c初始为0,一开始还没运算哪来的进位,这是个内层循环,数组a中的len
????????????????????????? //个元素都必须参与运算,都必须*n,这就是下面a[i]*n的来由

???? {?
?????????? a[i]= ( c+= a[i]*n ) % 10; c/=10;?? //c是进位,不用说了,c+=a[i]*n,a每个元素与n
??????????????????????????????????????????????? //相乘必须考虑低位是否有进位,有就加起来
???? }

?? ((a[i]=c)>0)?len++:0;? //最后一个元素也有进位吗,有的话就在当前的元素的下个数组位置直接等于进位值,并
????????????????????????? // 且数组的元素值 要加1,没有的话什么都不干,光一个0什么都不是
????????????????????
? }

?

?

?

5.大牛算法二

出处:http://bbs.csdn.net/topics/390025206

?

copy
    int?a[100000]={1},m=1;??
  1. main()??
  2. for(;n;n--)??
  3. for(c=i=0;i<m||c;)??
  4. ????????????a[i++]=(c+=a[i]*n)%10,c/=10;m=i;??
  5. for(;m;)??
  6. ????????putch(a[--m]+48);??
  7. }??

?

还有关于大数阶乘另有一个斯特林公式,不过这个是估算的值,并不是精确值,n的值越大,他的结果越精确。大家可以自己学习一下。

?

另外,网上关于大数阶乘的讨论也比较多。我也google了一些,学习后,感觉下面几个比较有意义。

还是先mark下。 便于以后温习。

http://www.cnblogs.com/qlwy/archive/2012/07/18/2598028.html

?

http://www.voidcn.com/article/p-zerxkjef-uw.html

?

http://blog.csdn.net/yxnk/article/details/1665052

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读