一.机器数和真值
1.机器数
一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.
比如,十进制中的数 +3 ,如果计算机字长为4位,转换成二进制就是0011。如果是 -3 ,就是 1011 。
2.真值
二进制对应的真值,就是带上符号的二进制
比如: 3对应的真值是+0011。-3对应的真值是-0011
二.原码
原码就是字节第一位是标志位,0代表正,1代表负,剩下位的真值的绝对值
比如8位字节:1的原码 0000 0001,-1的原码 1000 0001
三.反码
- 正数反码和原码相同
- 负数反码是原码除标志位之外,按位取反
- -1的原码 1000 0001
- -1的反码 1111 1110
四.补码
- 正数原码、反码、补码相同
- 负数补码是反码+1,符号位不变(如果超过了字节长度,会发生溢出)
- -1的原码 1000 0001
- -1的反码 1111 1110
- -1的补码 1111 1111
五.计算使用补码计算,而不使用原码、反码计算
- 让计算机来辨别符号位,会使基础电路设计的超级复杂,那么人们就开始研究让符号位不参与运算的方法
- 我们知道 1 - 1 = 1+(-1),只设计加法比较简单,人们开始探索加法,并尝试只保留加法,于是计算机减法就变成了加法。
原码的错误
- 如果使用原码计算 2 + (-1) = 0000 0010 + 1000 0001 = 1000 0011 = -3.这样会出错
- 为了解决这个问题,出现了反码
- 反码运算规则是符号位参与运算。同时符号位如果进位,会加到最低位,是循环进位。比如 11 + 10 = 10 (1是符号位)
- 2 + (-1) = (0000 0010 + 1111 1110)反 = 0000 0001 = 1
反码的问题
- 但是还会出现一个问题 +0 和 -0 的问题 +0 = 0000 000 ,-0 = 1111 1111。对计算机来说一个数字只能对应一个机器数,否则会在运算的时候出现错误。于是为了解决这个错误,出现了补码
- 补码: 补码的符号位一样可以参与运算,但是符号位进位会略去,不会循环
- 我们这样设定,0对应的是+0。所以0的编码是0000 0000
- 那么-0就不能表示0,人们就把-0 ~ - 127 整体向后偏移了1位,变成了 -1 ~ -128.至于怎么偏移,就是补码+1 变成反码。
- 然后我们可以顺着推,1111 1111 是 -1 。那么-128 就是 1000 000了。
- 至此解决了+0,-0的问题,而且int8的数据范围多了1个,变成了 -128 ~ 127
- -128 -1 = 127
- 这样,数据范围多了一个,而且又解决了问题,所以现在编程使用的都是反码表。8位字节范围是-128 ~ 127
- 如果使用原码表或反码表 1111 1111 ~ 0111 1111, 范围是 -127 ~ 127