什么是补码,怎么求补码

太过爱你忘了你带给我的痛 2022-06-07 08:09 375阅读 0赞

文章目录

    • 1 前言
    • 2 为什么要有补码?
    • 3 什么是补码?
    • 4 什么才是正真的补码?

1 前言

我的上一篇文章谈论到在汇编语言中
为什么 SHL 和 SAL 相同,而 SHR 和 SAR 不同
由此产生的疑惑更多了
到底什么是符号位? 进而补码又是什么?

2 为什么要有补码?

理由很简单,计算机内部只有加法器,并没有减法器
所以在计算机中,在我们人类眼中很简单的算术运算 2 - 3 = -1
计算机是无法完成的,那么依照计算机只能做加法,很显然的想到了 2 + (-3) = -1
因此数在计算机中必然要有特定的表示,那么补码就诞生了。

3 什么是补码?

无符号(unsigned)的一个字节的数表示如下:

  1. 0000 0000 = 0
  2. 0000 0001 = 1
  3. 0000 0010 = 2
  4. ...
  5. 1111 1111 = 255

有符号数(signed)的一个字节的数表示如下:

  1. 0000 0000 = 0
  2. 0000 0001 = 1
  3. 0000 0010 = 2
  4. ...
  5. 1000 0000 = 0
  6. 1000 0001 = -1
  7. ...
  8. 1111 1111 = -127

问题出现了,0000 00001000 0000 都代表着数字 0 0 0

不仅如此,且计算两个数相加会非常复杂,比如:

  1. 0000 0010
  2. + 1000 1100
  3. ---------------
  4. ???? ????

这必然给计算机运算器带来麻烦
于是约定,将1000 0000 设置为 -128,了解更多 点这里
因此范围被定义为: − 128 -128 −128 ≤ \leq ≤ X ≤ \leq ≤ + 127 +127 +127

虽然两个 0 的表示问题解决了,但是计算问题依旧相当复杂,于是就引进了补码

几乎所有的教材都这样写到:

正数的补码就是原码
负数的补码是符号位不变(1),其余位取反,然后加一

并且给出以下定义:

一个有符号数的最高位为符号位
0 代表这个数为正数
1 代表这个数为负数

依照这种定义,我们简单的来进行几个运算:
【例1】用补码计算 45 + 24

  1. 0010 1101
  2. + 0001 1000
  3. ---------------
  4. 0100 0101

正常答案69也是轻而易举的求出来了

【例2】用补码计算45 - 38

  1. 0010 1101
  2. + 1101 1010
  3. -----------------
  4. (1) 0000 0111

计算这一题的时候就有些犹豫了,因为进位已经到了符号位
那么我的符号位到底参与运算吗?
常理来说,符号位顾名思义,代表着数的正负,怎么可以参与运算呢?
事实却恰恰相反,符号位参与运算的结果才是正确的,如上例所示。

4 什么才是正真的补码?

上述的例子说明了一个非常矛盾的事情
把一个数的最高位定义为了符号位,计算中符号位却能参与运算
想必这也是很多人蒙在鼓里的地方了

补码的定义(以 8 8 8位字长数为例):


















表示 范围
X X X 0 0 0 ≤ \leq X X X ≤ \leq + 127 +127 +127
2 8 2^8 28- X X X − 128 -128 128 ≤ \leq X X X < 0 <0 <0

也就是说,正数的补码就是原码
而反码的补码等于位数 2 8 2^8 28 减去 X X X 的绝对值 ∣ X ∣ |X| ∣X∣,例如 − 38 -38 −38 的补码:

  1. 1 0000 0000
  2. - 0010 0110
  3. ----------------
  4. 1101 1010

所以 − 38 -38 −38 的补码为1101 1010

在这种定义下,没有反码的概念,也没有符号位的概念


参考:
[1] Signed Int: Bias/Excess Notation

发表评论

表情:
评论列表 (有 0 条评论,375人围观)

还没有评论,来说两句吧...

相关阅读

    相关 什么补码

    补码 用补码表示带符号的二进制数时,符号位与原码、反码相同,即用0表示正,用1表示负;数值位与符号位相关,正数补码的数值位与原码、反码相同。而负数补码的数值位是真值的数值位

    相关 关于负数补码

    原创 -------------------- 负数在计算机中是用补码的形式存储的,正数在计算机中是用原码的形式存储的。 正数求原码直接将十进制转二进制即可,负数的补码是