原码 | 反码 | 补码
■ 机器数
一个数在计算机中的二进制表示形式,叫做这个数的机器数
机器数是带符号的:在计算机用一个数的最高位存放符号,正 0 负 1。比如十进制数 +3,转换成二进制就是 0000 0011;对应的 -3 ,就是 1000 0011。这里的 0000 0011 和 1000 0011 就是机器数
■ 真值
因为符号位的缘故,机器数的形式值就不等于真正的数值。例如有符号数 1000 0011,其真值是 -3 而不是形式值 131
所以为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。0000 0001 真值是 +000 0001 == +1; 1000 0001 真值是 -000 0001 == -1
■ 原码
原码就是该整数转换成符号位的二进制数:如 +1 的原码是 0000 0001; -1 的原码是 1000 0001
■ 反码
正数的反码是其本身;负数的反码是在其原码的基础上,符号位不变,其余各个位取反。比如 +1 == 0000 0001(原码)== 0000 0001(反码); -1 == 1000 0001(原码)== 1111 1110(反码)
■ 补码
正数的补码是其本身;负数的补码是在反码的基础上 +1;比如 +1 == 0000 0001(原码)== 0000 0001(反码)== 0000 0001(补码); -1 == 1000 0001(原码)== 1111 1110(反码)== 1111 1111(补码)
注:这并不是补码的概念,只不过是负数的补码等于其反码 + 1
■ 值溢出
由于计算机中的数字用补码表示,例如 8 位的 byte 类型的表示范围为:[-128, 127]
补码和原码、反码不同,没有 +0 和 -0 一说,只有一个 0!而原码、反码存在 +0 和 -0,所以其取值范围是 [-127,127] 比如 0 == 0000 0000(补码) 127 == 0111 1111(补码)
8 位二进制下,-128 的补码是 1000 0000,它没有原码和反码!原因有两点:
1. 范围限制:8 位原码和反码能表示的有符号数范围是[-127, +127],-128 超出了这个范围,因此不存在对应的8位原码和反码
2. 补码的规则补全:补码为了消除原码、反码中 +0 和 -0 两个重复的 0,那么空出的 1000 0000 这个编码,刚好用来表示下限 -128,是人为规定的结果!
当 byte 类型的变量超上限 127 时
128 == 127 + 1
== 0111 1111(补码)+ 0000 0001(补码)
== 1000 0000(补码)
== -128
129 == 127 + 2
== 0111 1111(补码)+ 0000 0010(补码)
== 1000 0001(补码)
== -127
当 byte 类型的变量超过下限 -128 时
-129 == -128 - 1
== 1000 0000(补码) - 0000 0001(补码)
== 0111 1111(补码)
== 127
-130 == -128 - 2
== 1000 0000(补码) - 0000 0010(补码)
== 0111 1110(补码)
== 126
注:关于补码溢出的问题,可用一张图来描述(以 8 bit 为例)

我们会发现 -128 和 128 补码相同;-127 和 129 补码相同;-130 和 126 补码相同.......
■ 结语
有符号位的情况下的数字 0
1. 正 0 的原码、反码、补码、都是 0000 0000
2. 负 0 的原码是 1000 0000、反码是 11111111。注:负 0 没有补码
补码思想:计算机为何要引入补码 ?
1. 先看 2 + (-2)= 0;如果用原码表示则是 0000 0010 + 1000 0010 = 1000 0100,结果是 -4 这显然就扯犊子了。为了解决这个不正经的问题,要使 0000 0010 + ???? ???? = 0 那么问号必定是 1111 1110,就是说,这里问号所代表的这串数字就是 -2 的补码!为什么 ?继续往西看
2. 以现实中的钟表为例 10 - 2 = 8 和 10 + 10 = 20,其实 8 和 20 所表达的意思是一样的,都代表 8 点整!10 点后退 2 小时或前进 10 小时,都是代表的 8 点。那么这里加上的数字 10 和减去的数字 2 两个加起来刚好等于模(12),这两个数我们称之为同余数,这就是补码思想
3. 我们回到 2 - 2 = 0 这个问题,根据补码思想,2 - 2 其实等价于 2 + (256-2)。254 的二进制是 1111 1110,我们知道 1111 1110 是 -2 和 254 的补码(整不明白往上看值溢出的示例)
4. 最终我们要的是同余数 254 和 -2 之间的关系 :它们相同的补码 1111 1110,如何将其补码变成 -2 的原码 1000 0010 ?不就是补码先减去 1,然后按位取反!
注:补码其实就是一个代替负数的正数,这样就使计算机中只存在正数,计算简化且方便

浙公网安备 33010602011771号