char类型负数

负数的“溢出”如何理解

对于char类型变量,储存范围是-128到127,即-128到-1,0到127,128个数,对应char一字节8位,储存2^8=256个数。

对于有符号数来说,其大小有一个反直觉的地方,即-128_{2}是大于127_{2}的

对于二进制数而言,有以下规律

0000 0000 : 0

0000 0001 : 1

0111 1111 : 127

1000 0000 : -128,相当于127+1,故称第一位是符号位,此种算法保证-128是最小的负数,

1000 0001 :-127,相当于-128加一

那么,-128减一会发生什么呢?

代码示例:

#include<stdio.h>
int main(){
	char a,b,c;
	//char类型变量储存范围是-128到127,即-128到-1,0到127
	//各128个数,对应char一字节8位,储存2^8=256个数
	a=127;//a(2)=0111 1111
	b=a+1;//b(2)=1000 0000 
	printf("%d\n",b);//b=-128,即1000 0000是最小负数
	printf("%d\n",b-1);//输出-129,发生隐形转换 
	c=b-1;
	printf("%d",c); //输出127 
}

输出结果:

-128
-129
127

想要搞清楚为什么127加一等于-128,而-128-1出现两种不同的结果,我们就要弄清楚计算机里面的减法如何发生。 

减法

对于计算机来说,减法并非通过我们直观意义上理解的“-1借位”实现的,而是通过不断+(-1)实现的,现在我们以2-1为例看看这件事情是如何发生的。

设有char a=2;char b=-1;

那么我们知道

a = 0000 0010

b=  1111  1111

2-1即为a+b,假如忽略负数的符号位的功能性,将b视为二进制数255,会发生什么呢?

a+b = 257,溢出到第九位,即 1 0000 0001,char类型截断八位以上的数。

写到这里,想必减法规律已经明晰。通过加255的方式,使char类型数超限后截断,减去256,变相达到减一效果。类似地,对于大数,截去的结果是对256取余。

隐式转换

#include<stdio.h>
int main(){
	printf("sizeof(1) = %d\n",sizeof(1));
	printf("sizeof(1.1) = %d\n",sizeof(1.1));
	printf("sizeof(int) = %d\n",sizeof(int));
	printf("sizeof(double) = %d\n",sizeof(double));
	printf("sizeof(long long int) = %d\n",sizeof(long long int));
	printf("sizeof(float) = %d\n",sizeof(float));
	return 0; 
}

上面的代码出现了直接printf("%d",b-1);

由下可得,在C语言里面,整数会被转换成int,浮点数会被转化成double。

b-1的过程中,b被隐式转换成了int,负数提升时,符号位保留,即从

1000 0000转化成 1111 1111 1000 0000=-128(此处符号位保留,具体规则见“负数,补码的艺术”),此时再对-128-1不会溢出,产生回绕现象,故printf结果为-129

(负数那篇文章我还没写,写了会回来删掉这行)

sizeof(1) = 4
sizeof(1.1) = 8
sizeof(int) = 4
sizeof(double) = 8
sizeof(long long int) = 8
sizeof(float) = 4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值