PAT A1065的题解思考

本文探讨了编程中判断溢出的难点,重点在于整数溢出规则、浮点数IEEE754标准及其局限,以及为何A+B与C比较的问题。案例涉及longlong与double在[-263,263]范围内的精度问题,揭示了溢出在数据范围选择和比较运算中的重要性。

这道题的考察点是溢出的判断,参考组成原理的知识,首先两个符号不同的数相加是不可能溢出的。在计算机内部,两个正整数相加是采用补码相加,如果和的符号为负,就代表正溢出;同理两个负数相加,和的符号为正,则代表负溢出。

参考代码如下:

#include<stdio.h>
int main(){
  int line=0;
  long long a,b,c;
  scanf("%d",&line);
  for(int i=1;i<=line;i++){
      scanf("%lld%lld%lld",&a,&b,&c);
      long long temp=a+b;
      if(a>0&&b>0&&temp<0) printf("Case #%d: true\n",i);     
      else if(a<0&&b<0&&temp>=0) printf("Case #%d: false\n",i);   
           else if(temp>c)printf("Case #%d: true\n",i);
                else  printf("Case #%d: false\n",i);
  }
}   

一开始看到数据范围为[-263,263 ],右边界已经超出了long long的范围,于是本人使用double来记录a,b和c,以为double范围够大了,不会有问题,结果发现答案错误。经过查证,浮点数在计算机内部并不像整数一样直接化成补码存储,而是参照IEEE754标准来存储。

简单介绍一下IEEE754标准。该标准简单表示如下图。
IEEE754标准

在此标准中,浮点数类型会先转成一种类似于科学计数法的形式,分成数字符号,阶码(指数),尾数三个部分存储。存储时,最高位为数符位;其后为阶码,以移码方式存储,底总是2,就不存了;尾数采用原码存储,存储前必须经过在规格化,规格化过程中对应的阶码也会做调整,存储的尾数是纯小数。对于double类型,尾数最多能存53位(因为规格化后最高数值总是1,便没有存,以便可以多存一个尾数)。所以对于[-263,263 ],double无法存储63位尾数,存在精度丢失问题,所以说溢出这个考察点是逃不掉的。

至于A+B为什么不能直接与C相比较,本人查阅知乎link,发现表达式与变量比较,变量与变量比较这两者的比较机制是不一样的,看不懂(惭愧),但是本人觉得这个不能直接比较的问题是溢出造出的。

用long long没有出问题,因此数据范围应该有问题,[-263,263 )更符合。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值