2进制、8进制、10进制、16进制、左移右移速览、高位字节、低位字节、大端、小端、字节序、网络字节序、主机字节序
计算机底层数据均采用2进制补码形式存储,计算机内存地址均采用16进制数进行表示。
10进制数1234的2进制、8进制、10进制、16进制表示:
2进制:0b 0100 1101 0010、0100 1101 0010 B => 1234D
8进制:02322 => 0b 010 011 010 010 = 0b 0100 1101 0010 => 1234D
10进制:1234、1234D
16进制:0x4D2、4D2H => 0b 010 011 010 010 => 0100 1101 0010 B => 1234D
数的位数与值范围:对任意进制的任意数而言,其所用位数理论上无上限。但对计算机的数据类型而言,其所使用的位数便决定了表示的数的位数上限。例如:
数据类型int32表示32位有符号整数,用到了32个2进制位(4个字节),与其取值范围相同的数据范围如下:
二进制(用32位):-2,147,483,648 (-2^31) ~ 2,147,483,647 (2^31 - 1)
八进制(用11位):-2,147,483,648 (-2^31) ~ 2,147,483,647 (2^31 - 1)
十进制(用10位):-2,147,483,648 (-2^31) ~ 2,147,483,647 (2^31 - 1)
十六进制(用8位):-2,147,483,648 (-2^31) ~ 2,147,483,647 (2^31 - 1)
数据类型uint32表示32位无符号整数,用到了32个2进制位(4个字节),与其取值范围相同的数据范围如下:
二进制(用32位):0 ~ 4,294,967,295 (2^32 - 1)
八进制(用11位):0 ~ 4,294,967,295 (2^32 - 1)
十进制(用10位):0 ~ 4,294,967,295 (2^32 - 1)
十六进制(用8位):0 ~ 4,294,967,295 (2^32 - 1)
左移右移:在计算机底层数据表示中,通常使用的是二进制的补码表示数据,对于整数的左移/右移操作,只需乘以/除以2^x(2的x次幂)。
左移:在补码表示中,左移x位相当于乘以2^x(2的x次幂)。
右移:右移操作将一个数向右移动x位,相当于将该数除以2^x(2的x次方/幂)。如果原始数是正数,右移操作相当于向下取整;如果原始数是负数,则右移操作相当于向上取整。
左移、右移需要考虑溢出问题,例如2位二进制数11,令其左移/右移1位,分两种情形:
无符号数0b11(等于3D):左移1位变为0b10(等于2D)。
有符号数0b11(等于-1D):左移1位变为0b10(等于0D)。
无符号数0b11(等于3D):右移1位变为0b01(等于1D)。
有符号数0b11(等于-1D):右移1位变为0b01(等于1D)。
高位地址、低位地址:内存中的地址是递增的,如地址0x01低于地址0x02。假设有16个地址的连续空间,地址分别为从0x01、0x02……、0xe、0xf,则地址从左往右依次递增。
解析字节与16进制数:由于4个2进制位的值范围在0~15(如0b1111、0b0000)共16个值,这恰好是一个16进制数位的值范围。如果把连续8个2进制位数据视作整体,如8位二进制数 0b 1111 1110,等于10位8进制数 02104210420,也等于9位10进制数 286331152D,也等于2位16进制数 0xFE。而8位2进制也表示1字节,即1字节数据可由2位16进制数组成。
高位字节、低位字节、字节序:例如:有8位16进制数0x12345678,我们把它视作:0x12 0x34 0x56 0x78,共4个字节,等于32位2进制数 0b 0001 0010 0011 0100 0101 0110 0111 1000,这也是常见的4字节的int32数据类型。
考虑人类习惯下的16进制数【高位 0x12 > 0x34 > 0x56 > 0x78 低位】:
高位字节为该数左侧的字节数据(0x12最高),字节序列从高到低分别为为:0x12、0x34、0x56、0x78。
低位字节为该数右侧的字节数据(0x78最低),字节序列从低到高分别为:0x78、0x56、0x34、0x12。
另:0x123可看作0x0123进行拆分。
对于16进制数字0x12345678 和 4位16进制地址空间:
字节序 / 地址 | 低地址0x00 | 0x01 | 0x02 | 高地址0x03 |
---|---|---|---|---|
大端字节序 | 高字节0x12 | 34 | 56 | 78低字节 |
大端字节序 | 高位在前 | > | > | 低位在后 |
字节序 / 地址 | 低地址0x00 | 0x01 | 0x02 | 高地址0x03 |
---|---|---|---|---|
小端字节序 | 低位0x78 | 56 | 34 | 12高位 |
小端字节序 | 低位在前 | < | < | 高位在后 |
所以人类书写习惯的数字0x12345678是大端字节序8位16进制数。
而数字0x78563412是小端字节序。
网络/主机 字节序
对于IPv4地址:127.0.0.1,其等价于:
0x04 0x04 0x02 0x01
01111111 00000000 00000000 00000001 = 2130706433(主机字节序,一般为小端字节序,有的机器会用大端表示)
htons->
0x04 0x04 0x02 0x01
00000001 00000000 00000000 01111111 = 16777343(网络字节序,大端字节序)