带符号数表示

最近在看有关数值的表示有关的知识,因为实在太过混乱,所以在这里总结一下,主要讲原码,反码和补码这三种表示带符号数的表示方法。

一直在纠结-10010,+100011这样的还没编码的带符号的二进制数字用什么名词来表示,这也是我一开始看这个的时候有点懵逼的主要原因。所以在这里先约定一下:

用X表示-100,+1111这样的还没编码的带符号的二进制数,N表示X的位数,O(Original code)表示X的原码,用I(Inverse code)表示X的补码,用C(Complement code)表示X的补码。

开始之前再来行几点说明:

  • 所以的示范都是一个字节(1Byte)的空间作为样本

  • 所有的示意图均为Graphviz所实现

    开始

    原码,反码和补码这三种编码方法有个共通之处就是这三种编码的最高位都表示它所代表的数的符号,0表示正数,1表示负数,其余位表示数的大小(绝对值):

    image

    也就是说,N位的X的三种编码值O,I,C都有N+1位, 一个字节最多能表示7位的带符号二进制数.

原码

原码是最简单的表示法

  • N位的X对应得原码有N+1位

  • 最高位(也称符号位)是符号

  • 其余N-1位(也称数值位)是x的绝对值

下面有几个例子:

X O
+10010 0 10010
-11100 1 11100
+100 1111 0 100 1111

在一个字节上X的分布是这样的:

image

不难发现0有两个原码,1000 00000000 0000,这是编码的特殊性造成的

原码虽然表示直白,很好理解,但在运算的时候会带来不变。

反码

对于正数,反码表示法和原码表示法是一样的,他们俩的主要区别是负数的数值位表示上:

  • 正数最高位时0,负数最高位是1

  • 对于正数,其余N-1位是X的绝对值

  • 对于负数,其余N-1位是X的绝对值再按位取反

下面是几个例子:

X I
+10111 1 10111
+0 0 000
-100010 1 11101
-0 1 11111

同样,下面是反码的分布图:

image

可以看到,下方的+0…+127,-127,…-0,是完全大对称分布的,不难发现以下规律:

  • 同原码一样,0的反码也有两个,0000 00001111 1111

  • 求X的相反数X的反码只需将X的反码按位取反

补码

现在最常用的还是补码,这种最复杂的编码却凭着先天的优势成为三种编码中最常用的一种,补码对于正数的规则和反码,原码完全一样,这里主要说一下负数的反码表示

  • 负数的最高位还是1,后面N-1位是$2^{N-1}+X$的二进制表示

下面有几个例子:
X = -10010,$2^{7}+(-10010_{2}) = ‭1101110_{2}​$ ,因此X的补码位1 110 1110

下面还是给出它的分布图:
image

最显著的特点就是0只有唯一的补码0000 0000,不仅如此,负数补码就是在其反码的基础上再加一

若X >0:
$$
X_{O} = X_{I} = X_{C}
$$
若X<0
$$
X_{C} = X_{I}+1
$$

补码在计算上面有独特的优势:

如果:
$$
A + B = C
$$
那么有:
$$
A_{C} + B_{C} = C_{C}
$$

A,B,C是有符号数,I_A,是其对应的补码,然而这个结论在原码和反码上并不成立,这大概就是补码最成功的一点吧,但数据溢出问终究是存在的。