计算机底层运算逻辑

本文重点阐明了计算机中减法运算的实现以及反码、补码的意义。
对于加法来说,计算机很容易实现,

  举例:8 + 6 = 14;
  在计算机中,也就是
  0000 1000
  0000 0110
  ------------------------
  0000 1110

  0000 1110表示的则就是14. 没毛病

那么减法呢?

  举例: 8 - 6 = 2;
  在计算机怎么实现?
  首先int型在当前的计算机中大多数是占了32位,这里我们为了简便,就当作8位来处理(注意最高位是符号位,也就是8位的数据表示范围是:-128~127)

  在计算机的逻辑运算单元中,只有加法运算器,用来对两个数进行相加,并没有减法器的电路。因为对于减法运算,计算机也是用加法器来实现的,比如8 - 6,也可以表示成 8 +(-6),这样就变成了加法运算,问题变成了怎么让计算机表示出负数,有的朋友可能想:6是0000 0110,变成负数后不就是1000 0110了么,这的确没错。但是这样的表示并不能被加法器所支持,加法器是不知道负数的,尽管我们把最高一位定义成了符号位。
  8的二进制是 0000 1000
  -6的二进制是1000 0110
  0000 1000
  1000 0110
  --------------
  1000 1110

  而1000 1110表示的是-14,这显然不是我们要的结果。

  那么换一个思路,我们知道,现在我们举例的是8位数,最高的表示是127.

  举个时钟的例子。数字时钟上最大值是24点,这里的24点就是模。当到24点的时候,被取模后成为了0点。而减去1点和加上23点的效果都是一样的,无非就是补数和取模。24+23了后取模也是23,都是表示23点。

  所以8 - 6就跟 8 + (128 - 6)是一样的。(这里的128是模)

  于是乎,减法是可以被当作加法来运算的。

  所以计算机便有了反码的概念。正数的反码是自身,负数的反码则是除了符号位之后其他都取反(就相当于自己去加上摸之后取模后的结果)。

  但是反码后有一个问题,就是关于“0”的表示,那就是1000 0000和0000 0000都表示0,分别表示 +0 和 -0,而数学意义上并没有正负之分。所以必须消除其中一个

  于是有了补码的概念。正数的补码还是原码,负数的补码是原码在得到反码后再+1,

  让0只有在0000 0000的时候才表示0。
  而1000 0000表示 -128,(注意,-128是通过反码后的-0再加1得到的,-128是没有反码的。PS:正因如此,所以上文才说8位的数据表示范围是:-128~127,而不是从-127开始)

  于是乎 上面的 8 - 6 = 8+(-6)的问题

  8的原码、反码、补码都是原码:0000 1000
  而-6的原码是 1000 0110
  反码则是除符号位外,其余位取反:1111 1001
  补码则是反码+1,即: 1111 1010
  于是两个补码相加:
  0000 1000
  1111 1010
  ---------------------
  0000 0010

  0000 0010则是2, 正是 8 - 6的结果。

  到这里已经说明了减法的实现,其实也就是利用反码和补码的机制,以转换成加法运算。

  而这还没完呢,我们再来看一个例子:
  6 - 8 = -2

  这还不简单? 6 - 8就等于6 + (-8)嘛,于是:
  6的原码、反码、补码都是原码:0000 0110
  而-8的原码是 1000 1000
  反码则是除符号位外,其余位取反:1111 0111
  补码则是反码+1,即: 1111 1000
  于是两个补码相加:
  0000 0110
  1111 1000
  ---------------------
  1111 1110

  天哪,1111 1110的十进制数是-126啊,6 - 8怎么可能等于-126呢。

  显然,我们这个减法当作加法来运算貌似不是特别靠谱。只要当被减数的绝对值小于减数的绝对值的时候,计算出来的结果总是不对。

  当然了 不对是正常的,因为我们是用补码来计算,计算的结果也不是原码。这里因为符号位也参与了计算,所以最高一位并不是表示符号位了,1111 1110则是254了。想想?254 - 256 = -2,刚好是6 - 8的结果。这绝对不是偶然。

  我们把1111 1110求一次补码,先取得其反码是: 1000 0001
  则其补码则是:1000 0010

  天呐,1000 0010则就是-2,太神奇了。

  所以计算机的减法运算中,运算的结果是需要再求一次补码的

  在前一个例子8 - 6的2,是因为2是正数,反码、补码与原码都一样

  最后总结一下:
    概念:
    原码:带符号位的,我们表示的数值
    反码:正数的反码是原码,负数的反码是除了符号位之外其余位取反
    补码:正数的补码是原码,负数的补码是反码+1

  减法运算:
  通过反码的方式来将减法转换成加法运算,通过补码的方式消除了+0和-0的歧义。而在减法的运算结果中,还需要对结果进行补码。
 

原文地址:https://www.cnblogs.com/wsming/p/13208964.html