Skip to content

《关于补码》 #22

@wangsiyuan0215

Description

@wangsiyuan0215

负数在计算机中如何表示呢?

在计算机内部采用2的补码(Two’s Complement)表示负数。

本文中以 8 位机作为计算基础。

什么是补码?

它是一种数值的转换方法,要分二步完成:

  • 第一步,每一个二进制位都取反值,0 变成 1,1 变成 0。比如:0000 1000 取反为 11110111
  • 第二步,将上一步的得到的值 +1。即:
11110111 + 1 = 11111000

所以,1111 10000000 1000 的补码,也就是说 -8 在计算机中用 1111 1000 表示;

为什么要用补码来表示负数呢?

对于计算机,加减乘除是最基本的运算,要尽量设计的很简单;

  • 运算法则减去一个数等于是加上这个数的负数;
  • 计算机的基础电路只有加法,使得设计更加简单;

由于对于二进制的编码有三种方式:原码、反码和补码;

  • 原码:进行正数 + 负数的类减法所得的结果并不正确;
  • 反码:进行计算时,结果的真值部分是正确的,但是会有一个特殊的值:0。由于 0 是具有符号位是没有任何意义的,并且会有 1000 00000000 0000 两个编码表示 0;
  • 补码:进行计算可以完美解决真值、符号位和0的问题,同时由于 (-1) - (-127) = -128,补码会以 1000 0000 表示 -128,即还能够表示一个最低数。
  • 原码和反码表示的范围为 [ -127, 127 ],而补码可以表示 [ -128, 127 ];

补码的本质:

负数可以换成是 0 - 正数 得到的,因此 对于 -8 可以看做是 0 - (+8) 得到的;
那么对于二进制的来说即如下形式:

           0 0 0 0 0 0 0 0
        -  0 0 0 0 1 0 0 0
    -------------------------- 
           1 1 1 1 1 0 0 0

因为 被减数 0000 0000 小于减数 0000 1000,因此需要向上一位借 1,因此实质上被减数是 1 0000 0000

          1 0 0 0 0 0 0 0 0
       -    0 0 0 0 1 0 0 0
    -------------------------- 
          1 1 1 1 1 0 0 0 0

进一步观察可以发现,1 0000 0000 是由 1111 1111 + 0000 0001 所得,因此:

            1 1 1 1 1 1 1 1
       -    0 0 0 0 1 0 0 0
    -------------------------- 
            1 1 1 1 0 1 1 1
       +    0 0 0 0 0 0 0 1
    --------------------------            
            1 1 1 1 1 0 0 0

补码的转换步骤就是这么来的;

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions