1、计算机为了简化,只用了加法运算器,而不用再设计一个减法运算器
2、由于上述原因,计算机采用补码计算,而我们看到的数值显示形式是原码,换句话说,原码是我们脑子可以算出来的数值,而计算机只用补码计算
3、补码是很好理解的:
2-1=1这是我们脑中产生的,我们转换二制度看看 0010-0001=0001 计算机无法计算,因为只有加法运算器
那得给计算机找出-1的二进制表示方式,我们知道,两数相加等于0,即是一个数是另一个数的负数
但是找出二进制的相加等于0的数,并不好找,我们应该换个方法找出一个数相加是1111的二进制再加上0001那就是10000,最低位即是0000,找出一个相加等于1111的,这个简单,取一个数的反数即可
这个数,我们称之为反码,再加上0001后,我们称之为补码,即推演:-1->0001->取反1110->与1相加1110+0001->补码1111,那这个1110即是反码了,1111即补码
验证下:1-1=0 即0001+1111=10000,最高位舍去即0,正确
但是上面还有一个小问题
如果计算机采用补码计算,那么1的补码是多少呢?从上面验证可以看出,1的补码即0001即已可以计算机正确计算了,所以正数的反码,补码,与0001原码相同
假如说,计算机是4位存储,那15的二进制即1111,-15反码0000,补码0001,与1补码相同了,所以,我们还得区分下,正数与负数,规定最高位1表示负数,0表示正数,不参与原码,反码,补码计算
加了一个最高位标志,计算机存储也得加一位,5位存储:
-15=1 1111->取反1 0000->补码1 0001,15的补码是0 1111两数相加1 0001+0 1111=1 0 0000,最高位舍去,等于0,说明正确
最后一个问题-0会不会有问题?
-0=1 0000->取反1 1111->补码1 0000
-16=(-15)补码1001+(-1)补码1111=补码1 0000
+0=0 0000->补码0 0000
-0与+0 其实是一个数,没必须区别对待,因为这样产生了两个补码,对计算机实在是浪费,当-0与-16的补码又恰恰相同
好像是印度阿三提出的吧,我们知道,由于最高位用来标志是正与负数,故存储空间少了一位,那这个-0就给丢失的最大负数吧
总结:java int采用32位存储,按上面推算表示范围是-2的31次方至2的31次方减1,因为,最高位用来区分正负数,所以数值存储只能用到31位,又-0补给了负数,所以负数不用减1