大整数的计算问题
在c语言中,对于整数的计算,一般是使用int定义一个变量,然后再对其进行计算。很显然,这是存在问题的。因为int能够表达的整数是有范围的,它只能表达-2147483648到±2147483648之前的数。那如果要计算比这个范围还要大的数怎么办呢?
有人可能会说,int不行,那不是还有long int呢吗,再不行还有long long int啊。可是就算是long long int同样存在最大的表示范围。当我们遇到特别大的数,动不动就是几十位的加减乘除时,使用用int变量完全不能满足我们的需求,比如我就碰到过这样一道题:
洛谷p1009 阶乘之和
这是一道很简单的题目,要求计算出1的阶乘一直加到n的阶乘,但是它有一个特点就是给出的数据中有非常大的数。
我的代码本来是这样的:
#include<stdio.h>
int main()
{
int n;
int i,a=1,s=0;
scanf("%d",&n);
for(i=1;i<=n;i++){
a*=i;
s+=a;
}
printf("%d",s);
return 0;
}
浅显易懂,输入n的值然后计算阶乘之和,但是提交的时候出现了问题。
WA?为什么?查询输入数据后发现,原来是计算的结果超出了int的范围。那干脆大一点,用long long试试?
还是不对。long long也不行,那怎么办呢?
经过简单的思考以后,我想到:不能直接定义一个超大的变量,那就把它拆分成一位一位不就好了!这样的话就定义一个字符串,去一位一位的输出数据。
输出的问题解决了,但是紧接着就是新的问题:如何进行运算呢?整形的话直接使用运算符就好了,字符串呢?一位一位去运算吗?是不是还需要考虑进位的问题。
经过了短暂的构思和试验之后,我还是想出了解决的办法,具体的实现是这样的:
#include<stdio.h>
int main()
{
int n;
int a[1000],b;
int c[1000]={0},d;
int i,j,k,l=0;
int x,y=1;
scanf("%d",&n);
a[0]=1;
for(i=1;i<=n;i++){
for(j=1,x=0;j<=y;j++){
b=a[j-1]*i+x;
a[j-1]=b%10;
x=b/10;
}
while(x){
a[++y-1]=x%10;
x/=10;
}
for(k=0;k<y;k++){
d=c[k]+a[k]+l;
c[k]=d%10;
l=d/10;
}
}
for(i=y;i>=1;i--)
printf("%d",c[i-1]);
return 0;
}
首先还是定义一个int变量n,用来输入需要计算的阶乘值。字符串数组a用来记录阶乘每一位的数,对a进行运算得出每一轮的阶乘值。然后将a的值依次记录进字符串c中,在用一个循环输出字符串c,这样就大功告成啦!
提交试试
成功!
总结
当要计算一个特别大的数的时候,可以定义一个字符串数组,将大数的每一位依次填入字符串数组中,再对字符串数组的每个元素进行计算,最后输出。通过这种方法,就算是计算几百位上千位的数读不成问题!