用遇到问题到解决问题的角度来聊聊二进制之原码,反码,补码
1.大家都知道计算机是用二进制来存储数据的,那么数据有正负之分,二进制要怎么表示正负数呢?
正和负是2种状态,0和1也是2种状态,自然而然的就会想到用1位字节来表示正负,没错,先辈们也是这么想的,用第1位来表示正负,0表示正数,1表示负数.
这样就很好理解了,以8位为例,+5就是 0000 0101,-5就是 1000 0101,没错,这就是原码.好了,正负数都知道怎么表示了,那2个数之和要怎么处理呢?如果2个数都是正数,或者都是负数,可以保持符号位不变,其余二进制累加就可以了,比如+1+(+2) --> 0000 0001 + 0000 0010 = 0000 0011 = 3,但是如果一正一负的2个数,还要先比较2个数的绝对值,才能知道最后结果是正还是负,然后再将大值减小值,比如+1 + (-3) -->-负值较大,结果负数,第一位是1,计算值: 000 0011 - 000 0001 =000 0010 =,结果就是-2.
2.这样算下来,需要比较正负值的大小,如果能转成运算的过程应该会比较理想,那要怎么办才能直接运算呢?
通过观察,我们发现一个数加上它的按位取反的结果每位都是1,比如 1010 1010 + 0101 0101 =1111 1111,所以为了解决正数和负数相加的问题,我们可以将数进行取反操作,由于正数本来就满足它本身的加法,所以不需要做任何改变。那就将负数取反,符号位就不要变了,这就是反码.
还是以-3为例,原来-3 是 1000 0011,符号位不变,其他位取反就是 1111 1100,+1 还是原来的 0000 0001,那么+1 + (-3) --> 0000 0001 + 1111 1100 = 1111 1101,很明显1111 1101 是1个负数,为了方便计算,刚才-3我们是使用了反码,计算完了负数的反码还是需要还原回去的,1111 1101,符号位不变,其他位取反,那就是 1000 0010 ,这就是-2的原码.好了计算的问题已经解决了.通过刚才加法的观察,我们发现如果正数的绝对值没有负数大,那么累计后符号位就会变为1,如果正数的绝对值比负数大,那么累加后符号位就会变为0
3.这时我们又发现一个问题 0000 0000 表示 +0, 1000 0000 表示-0,而在实际使用中,我们只有用1个二进制数来表示0就可以了,那有没有更好的办法呢?
按我们正常的思维,0应该要使用0000 0000 来表示,那1000 0000 要表示什么呢?
我们来分析一下,以8位为例,正数是从 0000 0000 到 0111 1111,也就是从0到127,那负数呢?负数是从1000 0000 到1111 1111,如果以刚才原码的方式分析,那应该是-0 到-127,而我们现在是不想要-0了,那就往下挪1位吧,就变成-1 到 -128,原本-0的正码是1000 0000,反码就是1111 1111,那现在要用这个数来表示-1,这个就是补码,-1 为的正码是 1000 0001,反码是1111 1110,而刚刚得到的补码是 1111 1111,很明显两者差1,这是我们刚才下挪1位造成的,所以补码的来源就是正数取反,再+1
总结:
1.正数的原码,反码,补码都一样,第一位改为0
2.负数的原码,第一位改为1,后面的和正数一样
3.负数的反码为负数的原码,除符号位外全部取反
4.负数的补码为负数的反码 + 1,即负数的原码,除符号位外全部取反,+1
最后附上一些练习的笔记
正数 | 源码 | 反码 | 补码 | 负数 | 源码 | 反码 | 补码 | |
1 | 0000 0001 | 0000 0001 | 0000 0001 | -1 | 1000 0001 | 1111 1110 | 1111 1111 | |
2 | 0000 0010 | 0000 0010 | 0000 0010 | -2 | 1000 0010 | 1111 1101 | 1111 1110 | |
3 | 0000 0011 | 0000 0011 | 0000 0011 | -3 | 1000 0011 | 1111 1100 | 1111 1101 | |
4 | 0000 0100 | 0000 0100 | 0000 0100 | -4 | 1000 0100 | 1111 1011 | 1111 1100 | |
5 | 0000 0101 | 0000 0101 | 0000 0101 | -5 | 1000 0101 | 1111 1010 | 1111 1011 | |
加数 | 1 | 0000 0001 | 加数 | 1 | 0000 0001 | |||
被加数 | -1 | 1111 1111 | 被加数 | -5 | 1111 1011 | |||
和 | 0000 0000 | 0 | 和 | 1111 1100 | -4 | |||
加数 | 2 | 0000 0010 | 加数 | 5 | 0000 0101 | |||
被加数 | -2 | 1111 1110 | 被加数 | -1 | 1111 1111 | |||
和 | 0000 0000 | 0 | 和 | 0000 0100 | 4 | |||
加数 | 3 | 0000 0011 | 加数 | 2 | 0000 0010 | |||
被加数 | -3 | 1111 1101 | 被加数 | 4 | 0000 0100 | |||
和 | 0000 0000 | 0 | 和 | 0000 0110 | 6 | |||
加数 | 4 | 0000 0100 | 加数 | -2 | 1111 1110 | |||
被加数 | -4 | 1111 1100 | 被加数 | -4 | 1111 1100 | |||
和 | 0000 0000 | 0 | 和 | 1111 1010 | -6 |