oynix

于无声处听惊雷,于无色处见繁花

「原码 反码 补码 移码」一探究竟(上)

抛开复杂的理论,直探事物的本质。

0. 二进制

相比于二进制,十进制数字大家都比较熟悉。从右往左依次是个位、十位、百位、千位等,每个位置上的数字范围 [0, 9]。个位上的 1 表示 1,十位上的 1 表示 10,百位上的 1 表示 100,即从右向左的第 n 位就代表 10^(n-1):

1
761 = 7*100 + 6*10 + 1*1 = 7*10^2 + 6*10^1 + 1*10^0

而二进制,也是同样的道理,区别就是将 10 的 n-1 次幂变成了 2 的 n-1 次幂:

1
1101 = 1*2^3 + 1*2^2 + 0*2^1 + 1*2^0 = 8 + 4 + 0 + 1 = 13

有了这些基础概念,接着再来看下面的内容。

1. 这些「码」都是什么?

计算机中的数字一般分为两种,有符号数和无符号数。

原码,是一种计算机中对数字的二进制表示的方法。

有符号数,即用最高位的二进制位来表示正负,剩下的位来存储数据。

无符号数,即所有的二进制位都来表示数据,所以无符号数字无法表示负数,全部大于等于 0。

光看定义干巴巴的,用长度为 8 位二进制的类型举几个例子。

有符号数,最高位表示正负,0 表示正数,1 表示负数。

1
2
3
   7 : [0000 0111]
-3 : [1000 0011]
-127 : [1111 1111]

无符号数,没有符号位,全部二进制位用来表示数据。

1
2
3
  7 : [0000 0111] 
16 : [0001 0000]
255 : [1111 1111]

上面就是原码的定义,而反码、补码、移码都是在原码的基础上做了对应的变换。

反码:正数的反码就是其原码,负数的反码为,符号位不变,其余位取反,即 0 变 1,1 变 0。

补码:正数的补码就是其原码,负数的补码为在其反码的基础上再加 1,而在计算机中,整数都是以补码的形式存储的。

移码:将补码符号位取反,即为移码。

这几种码都是针对有符号数,而无符号数用原码就足够了,后面会对此说明原因。同样,也举几个例子说明。

1
2
 7 : [0000 0111] [0000 0111] [0000 0111] [1000 0111]
-3 : [1000 0011] [1111 1100] [1111 1101] [0111 1101]

关于定义,就说这些。既然原码就能表示数字,那为什么又会有这么多类型的码呢?而这些不同的码又是怎么来的呢?计算机中为什么要以补码而不是其他码来存储整数呢?移码又是做什么的呢?鉴于篇幅过长,下篇文章,会对这些问题一一说明。

------------- (完) -------------
  • 本文作者: oynix
  • 本文链接: https://oynix.com/2019/01/3c07e0b60f9b/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

欢迎关注我的其它发布渠道