二进制转十六进制:四位一个数字,不用算术
这个换算在做什么
它把一串二进制重新按四位分组,每组写成一个 16 进制数字。除了查一张十六个条目的对照表,不需要任何算术,所以这是最值得直接用眼睛完成的一种转换,也是位模式长到无法可靠扫读时的标准读法。
为什么四位一组刚好对得齐
16 是 2 的四次方,所以 4 个二进制位正好等于一位十六进制,永远不会有剩余,也不会出现半个组。这就是字节数据更青睐十六进制而不是八进制的原因:8 位能分成 2 组 4 位,而 3 不能整除 8。把最前面不足四位的组用 0 补齐,既能对齐又不改变数值。
二进制转十六进制对照表
十六种可能的四位组合及其十六进制数字。把这张表背下来就是全部的技能,之后二进制转十六进制只是抄写而不是计算。
| 二进制 | 十六进制 |
|---|---|
| 0 | 0 |
| 1 | 1 |
| 10 | 2 |
| 11 | 3 |
| 1010 | A |
| 1111 | F |
| 10000 | 10 |
| 101010 | 2A |
| 11111111 | FF |
| 100000000 | 100 |
调试时最常用的那一次转换
当一个协议字段、寄存器或位掩码以二进制到来,而文档却是按十六进制列出的时候,中间要做的就是这个翻译。按四位一组来做还能顺手校验:如果总位数不是 4 的倍数,说明中间掉了一位,你会在被这个值误导之前就发现它。
补零,不要靠猜
六个二进制位是一位半,而一位半并不存在。把最左边那组用 0 补满四位——101011 变成 0010 1011——再转换。靠猜来对齐,是数值最后差出十六倍的最常见原因。
常见问题
怎样手算二进制转十六进制?
从右往左每四位分成一组,最左边不足四位就用 0 补齐,然后把每组换成对应的十六进制数字。10011100 分成 1001 和 1100,结果是 9C。
为什么从右边分组而不是左边?
因为右端是最低位,分组必须跟着位权走才有意义。从左边分组时,只要长度不是 4 的倍数,每一位都会整体错位,那不是单纯没对齐,而是悄悄改变了这个数。
一个字节需要几位十六进制?
正好两位,因为一个字节是八位,而四位是一个数字。这个固定关系就是十六进制成为字节数据默认记法的原因,也是你能把内存转储读成一串两位数对的原因。
很长的二进制串也能转吗?
能。64 位的值会变成十六位十六进制数字,而且转换是精确而非近似的——全程使用整数运算,在浮点开始舍入的那一端也不会丢掉任何信息。
可以粘贴本来就带空格的二进制吗?
可以。空格和下划线会在转换前被去掉,所以从终端、数据手册或 diff 里复制来的二进制不必先整理。来源里怎么分组不影响最终的数值。