跳转到内容

数据表示基础:补码

来自维基教科书,开放书籍,开放世界

PAPER 2 - ⇑ 数据表示基础 ⇑

← 无符号二进制算术 补码 二进制分数 →



几乎所有计算机都完全使用二进制。这意味着它们只使用 0 和 1,而且计算机没有 - 或 + 符号。计算机必须以不同的方式表示负数。

我们可以通过将最高有效位 (MSB) 设置为 **符号位** 来表示二进制中的负数,符号位将告诉我们数字是正数还是负数。8 位数字的列标题将如下所示

-128 64 32 16 8 4 2 1
MSB LSB
1 0 1 1 1 1 0 1

这里,最高有效位是负数,其他位是正数。您从 -128 开始,像往常一样添加其他位。上面的例子是十进制的 -67,因为:(-128 + 32 + 16 + 8 + 4 + 1 = -67)

-1 的二进制表示是 11111111。

请注意,只有在数字被指定为 **有符号** 的情况下,您才将最高有效位用作符号位。如果数字是 **无符号** 的,则无论它是 1 还是 0,msb 都是正数。

有符号二进制数

如果 MSB 为 0,则数字为正,如果为 1,则数字为负。

0000 0101 (positive)
1111 1011 (negative)
方法:将负十进制数转换为二进制补码

假设您想将 **-35** 转换为二进制补码。首先,找到 35(正数)的二进制等效值

32  16   8   4   2   1 
 1   0   0   0   1   1

现在在 MSB 之前添加一个额外的位,将其设置为 0,得到

64 32  16   8   4   2   1 
 0  1   0   0   0   1   1

现在将所有位“翻转”:如果它是 0,将其改为 1;如果它是 1,将其改为 0

64 32  16   8   4   2   1 
 1  0   1   1   1   0   0

这个新的位表示 -64(负 64)。现在 **加 1**

64 32  16   8   4   2   1 
 1  0   1   1   1   0   0
                      + 1
 1  0   1   1   1   0   1

如果我们执行一个快速的二进制 -> 十进制转换,我们得到:-64 + 16 + 8 + 4 + 1 = -64 + 29 = **-35**

负数转换

[编辑 | 编辑源代码]

要找出补码数字的值,我们首先必须注意其符号位(最高有效位,最左边的位),如果该位是 0,我们像往常一样计算数字,如果该位是 1,则我们正在处理负数,需要找到它的值。

方法 1:将补码转换为十进制

要找到负数的值,我们必须找到并保留最右边的 1 及其右侧的所有位,然后将左侧的所有位翻转。以下是一个示例

1111 1011 note the number is negative
1111 1011 find the right most one

1111 1011 
0000 0101 flip all the bits to its left

现在我们可以计算出这个新数字的值,它是

128  64  32  16   8   4   2   1 
  0   0   0   0   0   1   0   1
                      4   +   1 = −5   (remember the sign you worked out earlier!)
方法 2:将补码转换为十进制

要找到负数的值,我们必须取 MSB 并对其应用一个负值。然后我们可以将所有标题值加在一起

1111 1011 note the number is negative
-128  64  32  16   8   4   2   1 
   1   1   1   1   1   0   1   1
-128 +64 +32 +16  +8      +2  +1 = -5

如何处理更复杂的例子?

方法 1:将补码转换为十进制
1111 1100 note the number is negative 

1111 1100 find the right most one

1111 1100
0000 0100 flip all the bits to its left
128  64  32  16   8   4   2   1 
  0   0   0   0   0   1   0   0
                      4         = −4   (remember the sign you worked out earlier!)
方法 2:将补码转换为十进制

要找到负数的值,我们必须取 MSB 并对其应用一个负值。然后我们可以将所有标题值加在一起

1111 1100 note the number is negative
-128  64  32  16   8   4   2   1 
   1   1   1   1   1   1   0   0
-128 +64 +32 +16  +8  +4          = -4

因此我们知道如何计算出给定负数的值。我们如何计算正数的负数版本?像这样,就是这样……

方法 1:将补码转换为二进制

取正数的二进制版本

0000 0101 (5)
0000 0101 find the right most one

0000 0101 
1111 1011 flip all the bits to its left

现在我们可以看到正数和负数之间的区别

0000 0101 (5)
1111 1011 (−5)
方法 2:将补码转换为二进制

取正数的二进制版本

从 -128 开始,我们知道 MSB 值得 -128。我们需要从这个数字开始往回计算

-128  64  32  16   8   4   2   1 
   1   1   1   1   1   0   1   0   
-128 +64 +32 +16  +8      +1      = -5
0000 0101 (5)
1111 1011 (−5)
练习:补码数字


将以下补码数字转换为十进制

0001 1011

答案

(正数)27

1111 1111

答案

(负数)0000 0001 = -1

0111 1101

答案

(正数)125

1001 1001

答案

(负数)0110 0111 = -103

1011 1000

答案

(负数)0100 1000 = -72

81(十六进制)

答案

(每个 HEX 字符使用 4 位)1000 0001(负数)-> 0111 1111 = -127

A8(十六进制)

答案

(每个 HEX 字符使用 4 位)1010 1000(负数)-> 0101 1000 = -88

将以下数字转换为以二进制表示的负数

0000 0001

答案

1111 1111

0110 0000

答案

1010 0000

0111 1111

答案

1000 0001

12(十进制)

答案

0000 1100 = +12 -> 1111 0100 = -12

67(十进制)

答案

0100 0011 = +67 -> 1011 1101 = -67

34

答案

0010 0010 = +34 -> 1101 1110 = -34

34(十六进制)

答案

(每个 HEX 字符使用 4 位)0011 0100 = +52 -> 1100 1100 = -54

7E(十六进制)

答案

(每个 HEX 字符使用 4 位)0111 1110 = +126 -> 1000 0010 = -126

补码值的范围

[编辑 | 编辑源代码]

如果 msb 用于提供负值,则最大可能值将受到限制。可能值的数目保持不变,这些数字的范围将包括负值以及正值。

使用补码表示的 个二进制位的范围

二进制减法

[编辑 | 编辑源代码]
示例:二进制减法

在二进制中,从一个数减去另一个数时,事情可能会变得非常混乱。

X (82 denary) 0101 0010
Y (78 denary) 0100 1110 −

从 X 中减去 Y 的一种更简单的方法是将 Y 的负值加到 X 的值上。

X−Y = X+(−Y)

为此,我们首先需要找到 Y(十进制 78)的负值。

0100 1110 find the right most one

0100 1110 
1011 0010 flip all the bits to its left

现在再次尝试求和。

   0101 0010     X( 82 denary) 
   1011 0010 +   Y(−78 denary)
   0000 0100
(¹)¹¹¹   ¹       the one carried over the bit 9 is ignored

结果是

128  64  32  16   8   4   2   1 
  0   0   0   0   0   1   0   0
                      4         = 4 = 82-78
练习:二进制减法

找出以下二进制和的答案,并展示你的计算过程。

  0110 1100 (108)
- 0000 0111 (7)

答案

将 0000 0111 转换为负数 1111 1001 = -7 将这两个数加在一起。

   0110 1100
 + 1111 1001
   0110 0101 = 101
(¹)¹¹¹¹         the one carried over the bit 9 is ignored
  0001 1111 (31)
- 0001 0011 (19)

答案

将 0001 0011 转换为负数 1110 1101 = -19 将这两个数加在一起。

   0001 1111
 + 1110 1101
   0000 1100 = 12
(¹)¹¹¹¹ ¹¹¹    the one carried over the bit 9 is ignored
  0111 0111 (119)
- 0101 1011 (91)

答案

将 0101 1011 转换为负数 1010 0101 = -91 将这两个数加在一起。

   0111 0111
 + 1010 0101
   0001 1100 = 28
(¹)¹¹   ¹¹¹    the one carried over the bit 9 is ignored
23 (hex)  - 1F (hex)

答案

将十六进制值转换为二进制。
0010 0011 = 23 十六进制或 35 十进制。
0001 1111 = 1F 十六进制或 31 十进制。
现在让我们找到 1F 的负值。
1110 0001 = -31
将这两个数加在一起。

   0010 0011
 + 1110 0001
   0000 0100 = 4
(¹)¹¹¹   ¹¹    the one carried over the bit 9 is ignored
  0001 0010 (10)
- 1110 0001 (-31)

答案

他们试图欺骗你。负数减去负数是什么? X - (-Y) = X + Y
让我们首先找到底部数字的值:1110 0001 -> 0001 1111 = 31
通过计算得出,我们得到了正值 (0001 1111) 将这两个数加在一起。

   0001 0010 (10)
 + 0001 1111 (31)
   0011 0001 = 49
(¹)  ¹¹ ¹¹     the one carried over the bit 9 is ignored
华夏公益教科书