计算机底层运算逻辑
本文重点阐明了计算机中减法运算的实现以及反码、补码的意义。
对于加法来说,计算机很容易实现,
举例: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的歧义。而在减法的运算结果中,还需要对结果进行补码。