这里都以整数为例,不考虑小数
原码:最原始的任何一个数值(不分进制),如1,12,101
补码:绝对值比原码大且符号相反的一个数值与原码相加后的数值(不分进制),如1相对于12的补码是:1+(-12)=-11
反码:针对二进制的数值将0变成1,将1变成0
计算机两数相加比两数相减容易计算,所以想办法将减法转成加法,因此引入了补码,如下十进制:
假如计算机是无法计算十位:3-2=3+(8-10)=(3+8)-10结果相同,这里减10相当于计算补码,可以看出最后结果是计算了一次补码的,8是相对于10的-2的补码,3+8=11,因为计算机无法计算十位,因此去掉十位就是3+8=1,相当于把结果计算了一次补码,所以选10来计算补码,即一般选最高位的下一位作为计算补码的值,如果是3-4,则3-4=3+(6-10)=(3+6)-10,因为3+6=9,没有超出最高位,所以最后还需进行一次补码的计算,所以9的补码是-1。因为计算机有最高位,只能计算到最高位,所以计算结果会出现这两种情况。
但又由于计算机是二进制,所以可以把0当作正数符号,1作为负数符号,这样的话就可以连符号位都进行计算,如上面的例子转成二进制(计算机假如最高显示4位,最高位为符号位),
无符号情况:3-2=011-010=001,计算机为了便于计算,转成有符号的加法,即引入补码和反码,为什么二进制引入反码,也是因为更容易计算,因为此处的假设只能显示三位数值位,所以-2的数值位为010,如何更容易计算补码呢,不妨给它多一位数值位,变成四位数值位,所以010相对于最高位的下一位即1000的补码为110,即110+010=1000,引入反码是如何使计算变得方便的呢,1000=111+001,可以看出111已经是三位数值位的最大值了,而111有个特点就是所有位都是1,因此任何两个三位二进制数相加结果为111的公式都变得简单,如101+?=111,很明显,1+0=1,所以把101的数值反过来就可以了,即010,所以叫反码是有原因的,这样101+010=111,然后再加个001就可以变成1000了,而101的补码(?+001为补码)计算方式为:101+(?+001)=1000,所以101+?=1000-001=111,明显?为101的反码,再加001就变成补码了,计算方便了很多,加上符号位就变成:0011+1110=10001,因为只能数值位只有三位,所以0001相当于计算了一次补码,如果是3-4因为结果的数值位没有超出三位,所以最后数值位还需要进行补码计算,所以为1001。由此看出只有负数才进行补码运算,所以规定了正数的反码和补码都为原码。
溢出问题:符号位改变则溢出,只有同符号相加,异符号相减的情况下会出现溢出
最后java:负数先转成补码,<<,>>含符号位的左移和右移,int为32位,>>>无符号右移,全部补0,>>符号位是1补1,是0补0,为什么没有<<<这个符号,是因为左移动符号位会改变,和用<<一样,所以不会增加<<<