c语言溢出该怎么算,解决整数运算溢出方法——C语言

嗨,大家好,这是我的第二篇博文,欢迎来踩

a4c26d1e5885305701be709a3d33442f.png,留在你们的小脚印呀!

正如大家所知,在C语言中整型变量用4个字节表示,表示范围略大于2乘以10的9次方,而长整型用8位表示,表示范围略小于2乘以10

的19次方。如果所要计算的数字或者计算的中间变量超过整型表示范围,则会出现错误结果,所以应该想办法避免这种错误的发生。

现在我们来看两个简单的例子:

A)输入n,计算S=1!+2!+3!+4!+。。。+n!的末6位(不含前导0)。n<=10的6次方。这里,n!表示前n个正整数之积。

样例输入:10

样例输出:37913

分析:如果按照以前的思路,先依次求算阶乘,再相加求和,再求除以1000000的余数,显然不可行。因为1000!早已超出长整型的表示范围,所以计算机是无法帮你表示出1000000!数值的,需要再次审题,找到突破口。发现,题目让我们求算末6位,对于加法、减法、乘法的整数表达式除以正整数n

的余数,可以在每步计算之后对n取余,结果不变。这就是我们要用到的有利条件。

基于这个思路,可以写出正确的编程代码如下:

#include

#include

int main(){

const int MOD=1000000;

int i,j,n,S=0,f;

scanf("%d",&n);

for(i=1;i<=n;i++)

{

f=1;

for(j=1;j<=i;j++){

f=f*j%MOD;

}

S=(S+f)%MOD;

}

printf("%d\n",S);

printf("Time used=%.2lf\n",(double)clock()/CLOCKS_PER_SEC);

return 0;

}

通过多测输入测试,我们可以发现一个问题,当输入数字大于等于25的时候,输出结果都是一样的820313,仔细分析的朋友可能已经知道原因了,前25个数字相乘的结果有6个0,所以再对1000000取余没有影响,结果相同。

B)输入不超过1000的正整数n,输出n!=1*2*3*4*.....*n的精确结果。

分析:细读题目,发现这道题好像没有上道题那么有突破点,显然中间结果会溢出,这该如何解决?换个思路,我们第一次学习乘法的时候是怎么做算术题的?对,列竖式,这道题可以模拟小学生算术题那样列算式求解。

用一个足够大的数组来存放要输出的结果,各元素初始化为0,只有第一个元素初始化为1,因为从1开始相乘。

这里f[0]表示个位,f[1]表示十位,f[2]表示百位,f[3]表示千位,依次递增一个数量级。

源代码如下:

#include

#include

const int

maxn=3000;//注意估计1000!大约等于4*10的2567次方,所以用3000个数组长度预存结果

int f[maxn];

int main(){

int i,j,n;

scanf("%d",&n);

memset(f,0,sizeof(f));

f[0]=1;

for(i=1;i<=n;i++)

{

int c=0;int sum=0;

for(j=0;j

{

sum=i*f[j]+c;

f[j]=sum;

c=sum/10;

}

}

for(j=maxn-1;j>=0;j--){

if(f[j])break;

}

for(i=j;i>=0;i--){

printf("%d",f[i]);

}

return 0;

}

不信的朋友可以试一试:输入30

输出265252859812191058636308480000000

这是长整型无法表示的整数,我们却让计算机帮我“手算”出来了,够朋友!

今天就写到这里,下周再见!

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值