恭喜你找到了宝藏,本篇内容非常清晰明了
先看图,short 和unsigned short的字节数是2,也就是说有2Byte,也就是说 16bit ,
即二进制 0000 0000 0000 0000
short是带正负号的, 所以取值范围不同,但是最大值和最小值差是一样的
short 32767-(-32768)= 65535
unsigned short 65535-0 = 65535 ,表示为二进制就是 1111 1111 1111 1111
为什么是这个取值呢?因为
2的15次方:32768
2的16次方:65536
正常人类理解,short取值为十进制的-1时,应表示为 1000 0000 0000 0001
而计算机不会进行“减”运算,都是进行“加”运算,所以1-1,会被计算机解释为 1+(-1)
short s1 = 1; 二进制 0000 0000 0000 0001
short s2 = -1;二进制 1000 0000 0000 0001
short s3 = s1+s2= 0 ;二进制0000 0000 0000 0001+1000 0000 0000 0001=1000 0000 0000 0010
上面s3的二进制
转化为十进制s3是 -2 而不是0,这是什么情况????
就是为了解决这一问题,才在计算机中引入了补码。
补码是正数不变,
负数是符号位不变,后面诸位取反,末位加一,-1由原来的
1000 0000 0000 0001,变成了 1111 1111 1111 1111
我们再重新计算一下
short s1 = 1; 二进制 0000 0000 0000 0001
short s2 = -1;二进制 1111 1111 1111 1111
short s3 = s1+s2= 0 ;
二进制0000 0000 0000 0001+ 1111 1111 1111 1111=(溢出一位1)0000 0000 0000 0000
还是用程序看起来更为直观:
运行结果下图所示(图中的0x意思就是16进制表示)
C语言程序默认将1前面的0都被省略了,并且默认%d输出出来是2字节,所以s2是八个f …非常尴尬
s1 = 1;十六进制 0001 ;二进制 0000 0000 0000 0001
s2 = -1;十六进制 f f f f ; 二进制 1111 1111 1111 1111
s3 = 0;十六进制 0000 ; 二进制 0000 0000 0000 0000
再看一个例子(二进制中,两个正数s1、s2前面的0再一次被省略,这个符号位0表示是正数)