负数在计算机中,以其补码的形式表示。

原码

英文为sign-magnitude,大意应该为符号-数值的组合。

在原码中,第一个数字代表符号位,1代表负数,0代表正数,余下的为数值位,用来表示具体的数值。

5用4位二进制原码来表示就是0101

-5用4位二进制原码来表示就是1101

CSAPP中给出的原码数学公式为:

由此我们能推断出SMAXw=2w-1-1,SMINw=-(2w-1-1)。

如八位二进制原码的范围应该为[-127,127]。

反码

英文为ones’complement

一个数字用原码表示是容易理解的,但是需要单独一个位来表示符号位,并且在进行加法时,计算机需要先识别某个二进制原码是正数还是负数,识别出来之后再进行相应的运算。

这样效率不高,能不能让计算机在进行运算时不用去管符号位,也就是让符号位参与运算呢?

要实现这个功能,我们就要用到反码。

反码是一种在计算机中数的机器码表示。对于单个数值(二进制的 0 和 1)而言,对其进行取反操作就是将 0 变为 1,1 变为 0。正数的反码和原码一样,负数的反码就是在原码的基础上符号位保持不变,其他位取反。

十进制 原码 反码
6 0000 0110 0000 0110
-3 1000 0011 1111 1100

下面我们来看一下,用反码直接运算会是什么情况:

step 1:我们以 6 - 3 为例,6 - 3 等价于 6 + (-3)

6 - 3 ==> 6 + (-3)
  0000 0110 //  6(反码)
+ 1111 1100 // -3(反码)
----------------------
  0000 0010 //  (反码)
  0000 0010 // 2(原码)

很明显通过反码进行 6 + (-3) 加法运算时,输出值比预期值差了一个 1

step 2:接着我们再来看下 1 + (-1) 的运算结果:

1 - 1 ==> 1 + (-1)
  0000 0001 //  1(反码)
+ 1111 1110 // -1(反码)
----------------------
  1111 1111 //   (反码)
  1000 0000 // -0(原码)

由上可知 1 + (-1) 的运算结果为 -0,而我们预期的值是 +0

step 3:我们继续看个示例 0 + 0

0 + 0 ==> 0 + 0
  0000 0000 // 0(反码)
+ 0000 0000 // 0(反码)
----------------------
  0000 0000 //  (反码)
  0000 0000 // 0(原码)

这里我们可以知道 -0 对应的原码是 1000 0000,而 +0 对应的原码是 0000 0000。虽然 -0 和 +0 代表的数值是一样的,但是在用原码和反码表示时它们是不同的。

通过以上的多个示例,我们发现使用反码进行加法运算并不能保证得出正确的结果

原因是用一个字节表示数字的取值范围时,这些数字中多了一个 -0。

为了解决反码出现的问题,就出现了补码。

补码

正数和 0 的补码就是该数字本身。负数的补码则是将其对应正数按位取反再加 1。

补码系统的 0 就只有一个表示方式,这和反码系统不同(在反码系统中,0 有两种表示方式),因此在判断数字是否为 0 时,只要比较一次即可。下图是一些 8 位补码系统的整数,它可表示的范围包括 -128 到 127,总共 256 个整数。

step 1:我们继续以 6 + (-3) 为例,来验证一下这个结论。

十进制 原码 反码 补码
6 0000 0110 0000 0110 0000 0110
-3 1000 0011 1111 1100 1111 1101

6 + (-3) 以补码形式的计算过程如下:

6 - 3 ==> 6 + (-3)
  0000 0110 //  6(补码)
+ 1111 1101 // -3(补码)
----------------------
  0000 0011 //  3(补码)

很明显这时我们得到了正确的结果

step 2:我们再来看一下以补码形式计算 1 - 1 的计算过程:

1 - 1 ==> 1 + (-1)
  0000 0001 //  1(补码)
+ 1111 1111 // -1(补码)
----------------------
  0000 0000 //  0(补码)

可以发现,补码完美解决了反码的问题。

补码思想的另一种推断

时钟中,8+2=10 和 8-10=10 最终的值都是一样的。

为了与二进制思想一致,这里把时钟改成了从0点开始。

8+2:从8点开始,顺时针增加2点

8-10:从8点开始,逆时针减少10点

由于 8+2 和 8-10 最终的值都是一样的,这样就可以将减法转为加法。

那么2与-10之间如何联系在一起的呢?

加法值 = 模 – 减法值

减法值 = 模 – 加法值

如果想知道8+2,模=12,加法值=2,减法值 = 12-2=10

计算101-010:

模=2³=1000

101-010 = 101+(1000-010) = 1011

“模”是指一个计量系统的计数范围。

时钟的计量范围是1~12,模=12。

n位的计算机计量范围是0~2^(n) -1,模=2^(n)。

“模”实质上是计量器产生“溢出”的量,它的值在计量器上表示不出来,计量器上只能表示出模的余数。任何有模的计量器,均可化减法为加法运算。

作者 admin

百度广告效果展示