前面楠神提到过,说计算机只会做加法运算,不会直接像人类的思想一样做乘法、减法、除法运算。计算机做乘法运算,就是快速地一次次相加。计算机做除法运算,就是快速地一次次相减。计算机怎么做减法运算呢?这就要我们先去了解位运算的原码、反码、补码知识,才能理解计算机做减法运算的原理。
原码:
就是“原来的二进制码”,其实就是我们可以理解的按10进制转换为二进制之后得到的一个字符码。
原码在数学上都是可以理解的。
但在实际的计算机的运行过程中,不止有正数,还有负数(俗称有符号数),却常常不用原码,所以就有反码,补码的问题。
在此基础上,规则:一个二进制数字的最高位是符号位,0表示正数,1表示负数。
举例(我们的计算机操作系统大部分都是64位的,一个整数通常是64位来表示,为了方便阅读这里以8位1个字节为例):
7: 0 0000111
-7: 1 0000111 【1理解为-,即符号位】
反码:
正数的反码是其本身。
负数的反码,就是将原码的非符号部分,每一位取反。
举例:
7: 0 0000111
-7: 1 1111000
补码:
正数的补码是其本身。
负数的补码,符号位不变,其余每一位取反之后,整体加1(即反码加1)
举例:
7: 0 0000111 【0*(-128)+0*64+0*32+0*16+0*8+1*4+1*2+1*1 = 7】
-7: 1 1111001【1*(-128)+1*64+1*32+1*16+1*8+0*4+0*2+1*1 = -7;1即是符号位-,也是数值位128】
从这可看出来,有符号数的计算机表示方式就是补码形式,在内存中的真实存储形式。
一个字节所能表示的有符号数区间范围为:-128 —— 127
-128(1000 0000)—— -1(1111 1111)
0(0000 0000)—— 127(0111 1111)
cpu内部加法运算模拟
$v1 = 5;
$v2 = 3;
$r1 = $v1 + $v2;
/*
cpu内部运算模拟示意:
5: 00000101 (既是原码,又是补码)
3: 00000011 (既是原码,又是补码)
+
--------------
00001000
可见,就是2的3次方(8)
*/
cpu内部减法运算模拟
$v1 = 5;
$v2 = 3;
$r1 = $v1 - $v2;
/*
实际应用中,cpu中的相减,会被转换为相加运算
因为只要对减数取负就得到一个新的负数,然后相加
类似这样:$r1 = $v1 + (-$v2)
cpu内部运算模拟示意:
5: 00000101 (既是原码,又是补码)
3: 00000011 (既是原码,又是补码)
-3: 10000011 (原码)
-3: 11111100 (反码)
-3: 11111101 (补码)
下面开始计算:5+(-3):
5: 00000101 (补码)
-3: 11111101 (补码)
+
-----------------------
00000010 (补码)
可见得到的结果是补码为2的值,则其原码自然也是2
*/
这节课的内容大家也就以了解为主,知道计算机的算术运算原理是靠二进制数字的补码相加得到的。这是计算机底层的东西,不得不佩服当初发明计算机的人如此聪明,衍生出反码、补码的知识。在后面的PHP学习和以后的PHP开发中是用不到本节的知识的。
想了解更多计算机底层只是,推荐买一本《深入理解计算机系统》这本书看看。