巴西作家保罗·科埃略的一句话:「如果你想成功,你必须遵守一条规则:永远不要对自己撒谎。」
大家好,我是柒八九。
今天,我们继续计算机底层知识的探索。我们来谈谈关于二进制的相关知识点。
如果,想了解该系列的文章,可以参考我们已经发布的文章。如下是往期文章。
文章list
你能所学到的知识点
- 用二进制数表示计算机信息的原因 推荐阅读指数 ⭐️⭐️⭐️⭐️
- 什么是二进制 推荐阅读指数 ⭐️⭐️⭐️⭐️⭐️
- 补数 推荐阅读指数 ⭐️⭐️⭐️⭐️⭐️
- 逻辑运算 推荐阅读指数 ⭐️⭐️⭐️
好了,天不早了,干点正事哇。
在
C
/Java
/JavaScript
等高级语言编写的程序中,数值、字符串和图像在计算机内部都是以二进制数值的形式来表现的
用二进制数表示计算机信息的原因
计算机内部是由IC
这种电子部件构成的。IC
的所有引脚,只有直流电压0V
或5V
两个状态。
也就是说,
IC
的一个引脚,只能表示两个状态
IC
的这个特性,决定了计算机的信息数据只能用二进制数来处理。由于1位(一个引脚)只能表示两个状态,所以二进制的计数方式就变成了0
、1
、10
、11
、100
...这种形式。
计算机处理信息的最小单位--位,就相当于二进制中的一位。
二进制的位数一般是8位、16位、32位····也就是8的倍数,这是因为计算机所处理的信息的基本单位是8位二进制数。8位二进制数被称为一个字节。
字节是最基本的信息计量单位
- 位是最小单位
- 字节是基本单位
内存和磁盘都使用字节单位来存储和读写数据,使用位单位则无法读写数据。
用字节单位处理数据时,如果数字小于存储数据的字节数(=二进制数的位数),那么高位上就用0填补。例如,100111
这个6位二进制数,用8位(=1字节)表示时为00100111
。
在程序中,即使是用十进制和文字等记录信息,在编译后也会转换成二进制的值。
对于用二进制数表示的信息,计算机不会区分它是数值、文字,还是某种图片的模式,而是根据编写程序的各位对计算机发出的指示进行信息的处理。
例如,00100111
这样的二进制数,即可以将其当做数值做加法运算,也可以当成‘
(单引号)文字而显示在显示器上。
具体进行何种处理,取决于程序的编写方式
什么是二进制
二进制数的值换成十进制数的值,只需将二进制的各数位的值和位权相乘,然后将相乘的结果相加即可。
位权
十进制数39
的各个数位的数值,并不只是简单的3
和9
。
3
表示的是3×10=30
9
表示的是9×1=9
这里的各个数位的数值相乘的10
和1
就是位权。数字的位数不同,位权也不一样。
- 第一位(
最右边的一位
)是10
的0次幂(=1) - 第二位是
10
的1次幂(=10) - 第三位是
10
的2次幂(=100) - 以此类推
位权的思考方式同样适用于二进制
- 第一位是
2
的0次幂(=1) - 第二位是
2
的1次幂(=2) - 第三位是
2
的2次幂(=4) - 以此类推
〇〇
的xx次幂表示位权,
- 其中,十进制数的情况下
〇〇
部分是10
,二进制数的情况下则为2
。〇〇
被称为基数 xx
,在任何进制数中都是数的位数-1
- 即第一位是
1-1=0
次幂 - 第二位是
2-1=1
次幂 - 第三位是
3-1=2
次幂
数值,表示的就是构成数值的各数位的数值和位权相乘后相加的结果
二进制数00100111
用十进制数表示的话是39
,因为(0×128)+(0×64)+(1×32)+(0×16)+(0×8)+(1×4)+(1×2)+(1×1)= 39
移位运算和乘除运算的关系
和十进制数一样,四则运算同样也可以使用在二进制数中,只要注意逢二进位即可。
移位运算
移位运算指的是将二进制数值的各数位进行左右移位的运算。
移位有左移(向高位方向
)和右移(向低位方向
)两种。
假设存在如下处理。把变量a
中保存的十进制数值39
左移两位后再将运算结果存储到变量b
中。
a = 39; b = a<<2; 复制代码
<<
这个运算符表示左移,右移时用>>
运算符。<<
运算符和>>
运算符的左侧是被移位的值,右侧表示要移位的位数。
在前面我们介绍过,无论程序中使用的是几进制,计算机内部都会将其准换成二进制数来处理,因此都能进行移位操作。
针对左移运算,空出来的低位要进行补0操作。
而右移操作,由于情况特殊,我们后面再做详细介绍。
此外,移位操作使最高位或最低位溢出的数字,直接丢弃就可以了。
下图,就是上述代码的运行过程。
移位运算就好比使用二进制表示的图片模式像霓虹灯一样左右流动的样子
补数
二进制数中表示负数值时,一般会把最高位作为符号来使用,因此我们把这个最高位称为符号位
- 符号位是
0
时表示正数 - 符号位是
1
时表示负数
计算机在做减法运算时,实际上内部是在加法运算。在表示负数时就需要使用二进制的补数。
补数就是用正数来表示负数
为了能获取补数,需要将二进制数的各位的数值全部取反,然后再将结果加1
例如,用8位二进制数表示-1
时,只需要求得1,也就是00000001
的补数即可。
- 将各数位的0取反加1,1取反成0
- 再将取反的结果加1
- 最后转化成
11111111
图例如下:
1-1在计算机内部是如何实现的
1-1
,也就是1+(-1)
,一眼就能知道答案,结果是0。
通过上文我们得知,-1
用二进制表示为11111111
。那么,在计算机内部计算1-1
,就变成了。
00000001 + 11111111 复制代码
结果确实为0
(=00000000
)。这个运算过程中出现了最高位溢出的情况,对于溢出的位,计算机会直接忽略掉。
即在8位的范围内进行计算时候,100000000
这个9位二进制数就会被认为是00000000
这一8位二进制数。
补数求解的变换方法就是取反加1
将二进制数的值取反加1的结果,和原来的值相加,结果为0
逻辑右移和算术右移的区别
右移有移位后在最高位补0
和补1
两种情况。当二进制数的值表示图形模式而非数值时候,移位后需要在最高位补0。 这就称为逻辑右移。
将二进制数作为带符号的数值进行运算时,移位后要在最高位填充移位前符号位的值(0
或1
)。这就称为算术右移。
- 如果数值是用补数表示的负数值,那么右移后再空出来的最高位补1
- 如果是正数,只需要在最高位补0即可
只有在右移时才必须区分逻辑位移和算术位移
左移时,无论是图形模式(
逻辑左移
)还是相乘运算(算术左移
),都只需要在空出来的低位补0即可。
符号扩充
以8位二进制数为例,符号扩充就是指在保存值不变的前提下将其准换成16位和32位的二进制。
不管是正数还是用补数表示的负数,都只需要用符号位的值(0或1)填充高位即可。
逻辑运算
在运算中,与逻辑相对的术语是算术。
- 将二进制数表示的信息作为四则运算的数值来处理就是算术
- 像图形模式,将数值处理为单纯的
0
和1
的罗列就是逻辑
计算机能处理的运算,大体可分为算术运算和逻辑运算。
- 算术运算是指加减乘除四则运算
- 逻辑运算是指对二进制数各数字位的
0
和1
分别进行处理的运算
- 逻辑非(
NOT
运算) - 逻辑与(
AND
运算) - 逻辑或(
OR
运行) - 逻辑异或(
XOR
运算)
逻辑非是指的是0
变成1
、1
变成0
的取反操作。
逻辑与指的是”两个都是1“时,运算结果为1
,其他情况下运算结果都为0
的运算。
逻辑或指的是”至少有一方是1“时,运算结果为1,其他情况下运算结果都是0的运算
逻辑异或指的是排斥相同数值的运算。“两个数值不同”,也就是说,当“其中一方是1,另一方是0“时运算结果是1,其他情况下结果都是0.
在进行逻辑运算时,都是对相对应的各数位分别进行运算
大家不要把二进制数表示的值当作数值,而应该把它看作是图形或者开关上的ON/OFF。并且,逻辑运算的运算对象不是数值,因此不会出现进位的情况。
下图表示的是对NI
的两个字母的图形模式进行各种逻辑运算后的结果。假设白色部分表示1,黑色部分表示0.
后记
分享是一种态度。
参考资料:《程序是怎样跑起来的》
全文完,既然看到这里了,如果觉得不错,随手点个赞和“在看”吧。