题目看懂了。此字体颜色为不懂部分。
这道题根本没思路。体会到了 基础重要性。
百度了数据溢出:
8+9=17
0 1000
0 1001
1 0001(正溢)
(-9)+(-8)=(-17)
1 0111
1 1000
0 1111(负溢)
int溢出超出了int类型的最大值,如果是两个正数相加,溢出得到一个负数,或两个负数相加,溢出得到一个正数的情况,就叫溢出。负数是以补码形式存储的,因此-1就是二进制的全1。
long long 取值范围-2^63~ +(2^63-1)
分析:
题目中两个整数相加可能会溢出(正溢出或负溢出),直接进行大小判断会造成错误,计算机组成原理中指出,如果两个正数之和等于负数或者两个负数之和等于正数,就是溢出,对于溢出后的具体范围,进行如下分析。
①A+B>=2^63时,A+B>C成立,但A+B会因为超过long long正向最大值发生正溢出。由于题目中A、B最大值均为2^63-1,所以A+B最大值为2^63-2,因此用long long 存储正溢出后值的区间为[-2^63,-2] (由(2^64-2)%(2^64)=-2可得右边界)。所以当A>0,B>0,A+B<0时为正溢出,输出true。
②A+B<-2^63时,A+B<C成立,但A+B会因为超过long long负向最小值发生负溢出。由于题目中A、B最小值均为-2^63,所以A+B最小值为-2^64,因此用long long 存储负溢出后值的区间为[0,2^63] (由(-2^64)%(2^64)=0可得左边界)。所以当A<0,B<0,A+B>=0时为负溢出,输出false。
③没溢出情况下。>true。<=false。
注意:
①经测试,数据中A、B并没有取到2^63,题目中范围可能写错了,应该是[-2^63,2^63)才更符合数据,否则就要用带负数的大整数运算了(因为long long存储2^63时会自动变成-2^63,无法区分左右边界)。
②A+B必须存到long long型变量中才可以与C进行比较,不可以在if条件中直接相加与C比较,否则会造成后两组数据错误。
#include<cstdio>
using namespace std;
int main(){
int t;
long long a,b,c;
scanf("%d",&t);
for(int i=1;i<=t;i++){
scanf("%lld %lld %lld",&a,&b,&c);
long long res=a+b;
bool flag;
if(a>0&&b>0&&res<0)flag=true; //正溢出
else if(a<0&&b<0&&res>=0)flag=false; //负溢出
else if(res>c) flag=true;
else flag=false;
if(flag==true) printf("Case #%d: true\n",i);
else printf("Case #%d: false\n",i);
}
return 0;
}