概述
最近在做IOT设备配网开发的时候,处理了很多跟二进制、字节相关的事情,总结了一下JavaScript中有关二进制方面的一些知识点。
二进制和字节
首先,现代计算机是基于二进制的,从现代计算机电路来说,只有高电平/低电平两种状态,即为0/1状态,计算机中所有的数据按照具体的编码格式以二进制的形式存储在设备中。
计算机通信和存储的时候都是以0101这样的二进制数据为基础来做处理的,这儿的一个0和1占的地方就叫bit(位),即一个二进制位。可以看出位(bit)是长度单位。8位组成一个字节,所以字节(Byte)也是长度单位。
位和字节的换算关系如下:
1Byte=8bit
1KB=1024B
1MB=1024KB(2的十次方)
二进制的计算
二进制数据的计算指的是位数据的计算,也就是位运算。
位运算分为以下几种操作:
符号 | 描述 | 运算规则 |
---|---|---|
& | 与 | 两个位都为1时,结果才为1 |
或 | ||
^ | 异或 | 两个位相同为0,相异为1 |
~ | 取反 | 0变1,1变0 |
<< | 左移 | 各二进位全部左移若干位,高位丢弃,低位补0 |
>> | 右移 | 各二进位全部右移若干位,正数左补0,负数左补1,右边丢弃。 |
注意:负数按补码形式参加按位与运算。
原码:用最高位表示符号位,其余位表示数值位的编码称为原码。其中,正数的符号位为 0,负数的符号位为 1。
正数的原码、反码、补码均相同。
负数的反码:原码的符号位保持不变,其余位逐位取反,即可得原码的反码。
负数的补码:在反码的基础上加 1 即得该原码的补码。
例如:
+11 的原码为: 0000 1011
+11 的反码为: 0000 1011
+11 的补码为: 0000 1011
-7 的原码为:1000 0111
-7 的反码为:1111 1000
-7 的补码为:1111 1001
位运算的应用很多,这里讲一个经典的,交换两个数。
通常交换两个数的做法如下,比如交换a和b:
let temp = a;
a = b;
b = temp;
如果我们用位运算来做
a ^= b;
b ^= a;
a ^= b;
使用位运算可以少定义一个变量temp,节省一个点内存空间;
字节顺序
字节顺序涉及到二进制数据在内存中怎么存储和网络数据的传输,假设我们定义一个变量 let value = 0x12345678,它在内存中是怎么存储的?
前面我们说过计算机里存储数据都是以二进制的形式存储的,假设一个整型占4个字节,那么先将它转成二进制:
parseInt(12).toString(2)
00010010 00110100 01010110 01111000。
按照正常阅读习惯,我们认为它在计算机内部的存储格式为:
低地址
buf[0] (0x12) -- 高位字节
buf[1] (0x34)
buf[2] (0x56)
buf[3] (0x78) -- 低位字节
高地址
这种存储模式叫大端模式。相对的还有小端模式
大端和小端
大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。
小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字