其实对于计算机来说,并不存在原码和反码,计算机存储的二进制数据都是以补码的形式存放的,自然对数据的运算也是直接用补码来运算(计算机中只有加法器没有减法器)
我们都知道正整数(包括0)的补码是它本身,负整数的补码是它的原码非符号位取反再加一
先来看个例子1:
十进制整数 | 二进制原码 | 二进制补码 |
7 | 0111 | 0111 |
-5 | 1101 | 1011 |
所以我们当计算机要计算7-5=?,实际上计算机直接认为是7+(-5)=?, 所以计算机把存储的7和-5对应的补码拿过来直接相加 0111+1011=0001 0010 ,我们看到数据溢出了,不过只要看后四位就行!我们要清楚计算所得的0010是直接存储在计算机中的!所以0010本质上来说是最终计算结果所对应二进制的补码(补码+补码=补码)。也就说我们要将0010这个补码逆推回所需要的原码,后四位0010的高位为0,显然是正数,那么0010这个补码对应的原码依然是0010!0010转换为十进制是2,7-5=2成立!
再来看个例子2:
十进制整数 | 二进制原码 | 二进制补码 |
7 | 0000 0111 | 0000 0111 |
-8 | 1000 1000 | 1111 1000 |
7-8=7+(-8)=? ---> 0000 0111 + 1111 1000=1111 1111 ,这次我们发现得到1111 1111 这个补码的高位是1,这就表明该补码对应的原码是一个负数。
对于负整数来说:补码=(原码)取反+1,那么原码=(补码-1)取反,注意取反时符号位不变!
1111 1111 -0000 0001=1111 1110 --->取反---> 1000 0001,很显然这个原码表示十进制的-1 ,7-8=-1成立!
关于byte整型的取值范围为(-128 ~ 127) 是为啥?
我们知道byte整型使用一个字节,也就是8位(bit)来表示二进制数据,那么直观的看应该是这样:
正数范围: 0000 0000 ~0111 1111
负数范围: 1000 0000 ~1111 1111
那么很显然 :
0000 0000 表示+0
0111 1111 表示+127
那么 1000 0000难道表示 -0 ,1111 1111表示-127 ??? 那我们在取值范围看到的-128是哪来的???当然不是!!
首先我们来解释1000 0000为什么不能代表 -0, 准确的说是为什么不能有 -0的存在!
1000 0000不能表示 -0 的原因
在数学中我们知道0既不是正数也不是负数,但是在计算机中由于二进制数据的高位不是0就是1 ,也就是说不是正数就是负数,因此二进制只能把0归为正数或负数,而将0表示为0000 0000 是非常自然的!所以说规定0在二进制中其实是一个正数,也就是+0!那么当然就不允许有-0这种形式的出现了,计算机不可能将一个数据以两种形式存放,否则会导致混乱,那么为了让1000 0000 不被闲置,我们自然地想让它表示其余某一个数!那么表示什么数呢?这里我们先放一放
1111 1111不能表示-127的原因
这其实是初学者极其容易犯的毛病,之前讲过,对于计算机来说,并不存在原码和反码,计算机存储的二进制数据都是以补码的形式存放的,因此对于1111 1111这个二进制数据来说,如果我们要得到它的十进制数据是需要求其原码的,显然1111 1111的原码是-1才对!也就是说对于计算机来说1111 1111代表的就是-1。因此我们也可以容易的得到1000 0001表示的才是-127。其实更广义的说,不只是1000 0000 ,只要是所有多字节二进制数中,最高位为1 其余位都为0的二进制数据都使用人为表示的1个数,这个数在十进制中就是-2^n (n表示除符号位以外的其余位位数)
例如2个字节的二进制数据1000 0000 0000 0000 表示-2^15=-32768 ;注意 如1000 0000 0000其实是0000 1000 0000 0000,所以它不是以为的-2^11,而是2^11
综上所述
0000 0000 ~0111 1111 表示 +0 ~ +127
1111 1111 ~1000 0001 表示 -1 ~ -127
咦,我们好像漏了 1000 0000 这个二进制了,哈哈,到现在为止一切都解决了,其实我们人为规定 1000 0000表示十进制中的-128!当然我们不可能说通过 1000 0000这种二进制求其原码得到某一个数,因为非高位全是0,无法再借位减1了!
其实这种规定是很自然的,1000 0000 -0000 0001=0111 1111,而0111 1111 这个补码表示的是+127,我们可以将 1000 0000这个二进制作为正数和负数之间的一个分水岭(尽管1000 0000本身代表负数),1000 0000再进位就会进入负数范围,若借位就会进入正数范围,就好似1000 0000(-128)将 1000 0001(-127) ~0111 1111(+127)首尾连接了起来形成了一个闭环!!!
讲到这里 所有的疑问就解决了,感谢你的观看!