问题:byte类型的127加上1,得到的结果是-128
一、原码
计算机只能存储、计算二进制数据,一个byte有8个字节。那要计算两个十进制的数据,需要先将十进制数据转换为二进制数据。
例十进制:
7+1=8
转换为二进制计算:8字节,高位补0
00000111+00000001=00001000
对于正数的计算,这个没有问题。但是对于负数如何表示?再去维护一个符号用于表示负数的代价过于高昂,于是采用了在8字节的最高位表示为1用于表示负数,只用7位表示计数。于是 -1 表示为 10000001。对于正数,不需要额外的处理,反码就是源码本身。
例十进制:
2−2=0
反码的出现不仅表示了负数,而且还把减法可以表示为加上一个负数,从而不再需要设计减法计数器电路。但是计算会出现如下问题:
00000010+10000010=10000100
转换为二进制可知,计算的结果为-4,计算出现了问题。
二、反码
为了解决这个问题,出现了反码。同样,正数的反码是其本身;对于负数,就是最高位的符号位不变,其余位置取反,例如-2二进制是10000010,则其反码为11111101,
例十进制:
2−2=0
则二进制:
00000010原码+10000010原码
00000010反码+11111101反码=11111111反码
先转换为反码,再计算,得到的是反码的结果,但是要得到真正的结果,还需要再转为原码。
11111111反码−−>10000000原码
结果为-0,可见,结果是正确的,但是出现-0的结果需要处理。
三、补码
同样,为了解决出现-0的情况,出现了补码。同样,正数的补码是其本身;对于负数,负数的补码是其反码+1。例如,-2的二进制是10000010,则其反码为11111101,则其补码为11111110。
例十进制:
2−2=0
则二进制:
00000010原码+10000010原码
00000010反码+11111101反码=11111111反码
00000010补码+11111110补码=00000000补码
计算十进制结果:由于最高位是0,则表示正数,补码是原码本身,所以原码为00000000,结果为0
四、已知补码求原码
已知某补码为 1111 1110,求原码
1.正数:
如果以0开头,则证明其为正数,原码就是补码本身,如 0000 0010的补码就是本身
2.负数:
如果以1开头,则证明为负数,先 将最高位不变,其余7位取反。
11111110补码−−>取反10000001
再+1,即可得到原码(-2):
10000001+00000001=10000010原码
五、普通结果验证
5-3与3-5
1.运算1:
5+ (-3) (省略了反码的计算步骤)
- 原码:00000101原码+10000011原码
- 补码:00000101补码+11111101补码=00000010补码
- 结果:00000010补码是正数,原码为本身,所以十进制为2.
2.运算2:
3+(-5) (省略了反码的计算步骤)
- 原码:00000011原码+10000101原码
- 补码:00000011补码+11111011补码=11111110补码
- 结果:11111110补码是负数,原码为最高位不变,其余位取反再加1,则为:10000010,结果为-2。
六、-128问题
byte类型127+1 = -128
- 原码:01111111+00000001
- 补码:01111111+00000001=10000000
- 结果:-128没有原码与反码,只有补码,按照约定,补码为10000000则为-128。
七、延申:
实际上,现代计算机中的逻辑计算电路,都是按照补码来进行存储的。所以实际的计算过程中,直接使用补码。