PAT_1065. A+B and C

#include <iostream>
using namespace std;
long long int a,b,c,res,test;
int main()
{
	//test = ((long long)1 )<<63;
	//printf("2^63=%lld\n",test);
	int M;
	bool flag;
	scanf("%d",&M);
	for(int i=1;i<=M;i++)
	{
		scanf("%lld%lld%lld",&a,&b,&c);
		res=a+b;
		//printf("a=%lld b=%lld res=%lld \n",a,b,res);
		if(a>0&&b>0&&res<=0)
			flag = true;
		else if(a<0&&b<0&&res>=0)
			flag = false;
		else
			flag = res > c;
		if(flag==true)
			printf("Case #%d: true\n",i);
		else
			printf("Case #%d: false\n",i);
	}
	return 0;
}


借着这道题的机会复习了计算机组成原理原码 反码 补码 相关的知识。

主要深入理解了计算机中的加法运算,因为计算机做减法不方便,于是有了补码,补码可以让减法与加法做同样的运算,在运算时不需要判断符号位,大大方便了机器的加减法运算。

我们来谈论一下这道题的想法,一开始我以为是大数加法减法,这样做代码量太大,这个思路就被否定掉了,后来想到long long int可以表示的范围,根据补码的相关知识,N位可以表示的范围是-2^N-1 ~ 2^(N-1)-1 。在本题中,用 long long 恰好与题目中的范围契合,是 -2^63 ~ 2^63 -1 。 

本题主要就是要解决一个运算时溢出的问题,我们知道,在补码运算中:

如果是两个正数相加,因为两个数的符号位都是0,符号位相加为0;而溢出时,最高位进位为1,因此 0+1 永远为1 ,也就是说,运算结果最高位也就是符号位一定为1,也就说明正数+正数溢出时一定得到(非正数)。

如果是两个负数相加,溢出时,举个例子,如果是8位数的负数加法,我们知道,8位能表示的范围为-128~127,两个8位的负数相加,如果溢出了,溢出区间为[-129,-256],我们先用9位的补码表示这个运算结果所在区间,就是[1 0111 1111,1 0000 0000], 我们发现,运算结果范围的第8位一定为0,由于我们机器中只有8位来表示这个数,所以我们脑补的第9位是不存在的,也就是说当溢出发生时,符号位必然为0,也就是说两个负数相加时得到的符号位一定为0,也就一定是一个非负数。

有了计算机中补码加减法运算溢出的相关知识,此题也就迎刃而解了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值