大数阶乘
来源:互联网 发布:下载文件进度条js特效 编辑:程序博客网 时间:2024/06/14 10:46
C/C++语言中,int范围[-2^31,2^31 -1] 即 [-2147483648,2147483647]。
在进行阶乘运算中,12!=479001600,13!=6227020800,也就意味着超过13的阶乘就不能用int型进行存储。对于大数的阶乘,要换一种方式进行存储。
输入一个数值n,首先要估算n!的位数:
int getSize(int n) //计算结果的大概位数{ int i,j,num; for(i=1,j=n;j/10>0 || j%10>0;i++) { j/=10; } //num=n*--i+1; //此计算式为多次总结归纳得到 num=n*--i/3+1; //一个int存储的数字的范围为0~9999,按理说是n*--i/4+1,此处多申请一些以防开辟的空间不足 return num;}
通过此函数得到的位数会比实际的位数要多。
得到位数size之后,申请一个长度为size的int型数组,初始化末位为1,其余全为0;
然后从末位起倒着乘以每一个数,将数组中每一个数字的范围为0~9999,超过范围的数字向前进位。最后将结果通过string字符串返回。代码如下:
string factorial(int n){ string outp; int *temparr,num; int getSize(int n); int getNumLength(int n); int i,j,k; int wsize=10000; int size=getNumLength(wsize)-1; num=getSize(n); temparr=new int [num]; for(i=0;i<num;i++) { if(i==num-1) temparr[i]=1; else temparr[i]=0; } if(n==0) temparr[num-1]=1; else { for(i=1;i<=n;i++) { int count=num-getSize(i)-1; for(j=num-1;j>=count && j-1>=count;j--) temparr[j]*=i; for(k=num-1;k>=count && k-1>=count;k--) { if(temparr[k]>wsize) { temparr[k-1]+=(temparr[k]/wsize); temparr[k]=(temparr[k]%wsize); } else continue; } } } int midd=0; for(i=0;i<num;i++) { if(temparr[i]==0) midd+=1; else break; } char s[8]; sprintf(s,"%d",temparr[midd]); //从第midd位开始为非0数 outp+=s; for(i=midd+1;i<num;i++) { sprintf(s,"%04d",temparr[i]); //四位有效数字,不足的情况用0填充 outp+=s; } if(temparr) { delete [] temparr; temparr=NULL; } return outp;}
其中,int getNumLength(int n)函数的实现代码为:
int getNumLength(int n){ if(n==0) return 1; else if(n<0) return -1; int size=0; while(n) { n/=10; ++size; } return size;}
main函数中:
int main(int argc, char* argv[]){ int getSize(int n); int getNumLength(int n); string factorial(int n); cout<<"//------------------------------大数阶乘------------------------------//"<<endl; cout<<"//--------- 数组求阶乘,为方便运算,原则不大于100000,否则会很慢 --------//"<<endl; int n; cin>>n; string s; double timebegin=(double)clock()/CLOCKS_PER_SEC; if(n<0) { cout<<"输入有误!!!"<<endl; return 0; } else { s=factorial(n); cout<<n<<"!="; cout<<s<<endl; if(n>=30) //启用科学计数法 { cout<<n<<"!="<<s[0]<<"."; for(int i=1;i<20;++i) cout<<s[i]; cout<<"e+"<<s.size()-1<<endl; } } printf("time: %.6f\n\n",(double)clock()/CLOCKS_PER_SEC-timebegin); system("pause"); return 0;}
运行结果:
20的阶乘:
1000的阶乘:
20000的阶乘:(此时的时间包括输出的时间,输入到输出结果光标闪动4次左右)
希望对大家有帮助。
0 0
- 大数阶乘
- 大数阶乘。
- 大数阶乘
- ~阶乘~大数
- 大数阶乘
- 大数阶乘
- 大数阶乘
- 大数阶乘
- 大数阶乘
- 大数阶乘
- 大数阶乘
- 大数阶乘
- 大数阶乘
- 大数阶乘
- 大数阶乘!!
- 大数阶乘
- 大数阶乘
- 大数阶乘
- sql入门--前三章
- android异常收集-关于导入文件出现错误,运行不起来
- Turbo Cache技术
- NYOJ 1058 部分和问题 (DFS)
- C++11系列-改进的类型推导:auto、decltype和新的函数语法
- 大数阶乘
- HDU 2553(n皇后)
- Log4j配置详解
- Eclipse Plug-ins for Gradle: buildship 插件安装说明
- Linux常用命令
- caffe示例实现之4在MNIST手写数字数据集上训练与测试LeNet
- qtp的运行原理
- 从Object-C -> Swift3.0
- spring 在启动服务器的时候报错 Could not open ServletContext resource [/WEB-INF/dispather-servlet.xml]