← 全部文章 计算机基础

进制:从数苹果到互相转换

2021 年 6 月 15 日 · 2 分钟读完

目录
  1. 四种常见进制
  2. 「10」不一定是十
  3. 偷懒的办法:系统计算器
  4. 其他进制转十进制:按权展开
  5. 十进制转其他进制
  6. 整数:除基取余,倒着读
  7. 小数:乘基取整,正着读
  8. 二进制和八、十六进制互转:分组
  9. 延伸

工作里遇到要手动换算负数的情况,想做个记录。在讲负数之前,得先把进制和进制转换弄清楚。这一篇是「数字在计算机里」系列的第一篇。

四种常见进制

进制 英文缩写 用到的数字 规则
二进制 BIN / B 0、1 逢二进一
八进制 OCT / O 0 ~ 7 逢八进一
十进制 DEC / D 0 ~ 9 逢十进一
十六进制 HEX / H 0 ~ 9、A ~ F 逢十六进一

拿十进制来说,9 + 1 个位满十归零,向十位进一,结果从一位数变成了两位数 10。其他进制完全一样,只是「满几」不同:

二进制:  1 + 1 = 10
八进制:  7 + 1 = 10
十六进制:9 + 1 = A,F + 1 = 10    (A~F 分别代表 10~15)

「10」不一定是十

每种进制加到最后都会出现 10,但它们代表的数量并不相同。假设一共有 16 个苹果:

十进制数:  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
二进制数:  1, 10, 11, 100, 101, 110, 111, 1000, ..., 1111, 10000
八进制数:  1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 20
十六进制数:1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, 10

16(D)、10000(B)、20(O)、10(H)都是 16 个。表示方法不同,数量相同。

偷懒的办法:系统计算器

只是想换算一下的话,Windows 自带的计算器就够了:搜索「计算器」打开,左上角菜单切到「程序员」模式。

HEX、DEC、OCT、BIN 四行里,点哪一行就用哪种进制输入,另外三行同步显示换算结果。比如在 DEC 下输入 16,会看到 HEX 10、OCT 20、BIN 0001 0000。

其他进制转十进制:按权展开

先看二进制里几个特殊的数:

二进制:0001  0010  0100  1000
十进制:  1     2     4     8
权值:   2^0   2^1   2^2   2^3

每一位上的 1 都代表 2 的某次方。所以 1111 = 2^3 + 2^2 + 2^1 + 2^0 = 8 + 4 + 2 + 1 = 15。

规则可以推广到任何进制:从右往左第 n 位上的数字 a,代表 a × 基数^(n-1),把每一位加起来就是十进制结果。

二进制   1111 0001 = 1×2^7 + 1×2^6 + 1×2^5 + 1×2^4 + 0×2^3 + 0×2^2 + 0×2^1 + 1×2^0 = 241
八进制   1234 5670 = 1×8^7 + 2×8^6 + 3×8^5 + 4×8^4 + 5×8^3 + 6×8^2 + 7×8^1 + 0×8^0 = 2739128
十六进制 123A BCDE = 1×16^7 + 2×16^6 + 3×16^5 + 10×16^4 + 11×16^3 + 12×16^2 + 13×16^1 + 14×16^0 = 305839326

带小数的也一样,小数点后面的指数从 -1 开始往下数:

二进制 1111.0101 = 2^3 + 2^2 + 2^1 + 2^0 + 0×2^-1 + 1×2^-2 + 0×2^-3 + 1×2^-4 = 15.3125

十进制转其他进制

整数:除基取余,倒着读

十进制 372 转二进制(除二取余):
372 ÷ 2 = 186 …… 0
186 ÷ 2 =  93 …… 0
 93 ÷ 2 =  46 …… 1
 46 ÷ 2 =  23 …… 0
 23 ÷ 2 =  11 …… 1
 11 ÷ 2 =   5 …… 1
  5 ÷ 2 =   2 …… 1
  2 ÷ 2 =   1 …… 0
  1 ÷ 2 =   0 …… 1
从下往上读余数:1 0111 0100(B) = 372(D)

转八进制(除八取余):372 → 余 4,46 → 余 6,5 → 余 5,读作 564(O)
转十六进制(除十六取余):372 → 余 4,23 → 余 7,1 → 余 1,读作 174(H)

十六进制的余数可能大于 9,别忘了换成字母。比如 444:余数依次是 12(C)、11(B)、1,读作 1BC(H)。

小数:乘基取整,正着读

0.125 转二进制(乘二取整):
0.125 × 2 = 0.25 …… 取整 0
0.25  × 2 = 0.5  …… 取整 0
0.5   × 2 = 1.0  …… 取整 1,小数部分为 0,结束
从上往下读:0.001(B) = 0.125(D)

但很多小数永远乘不完,比如 0.1458 转二进制会得到 0.001001... 一直循环下去。存多少位取决于给这个数分配了多少空间,这也是浮点数有精度误差的根源,系列第三篇会细讲。

二进制和八、十六进制互转:分组

1111(B)等于 15,再加 1 就是 16,正好在十六进制里进一位。所以 4 位二进制正好对应 1 位十六进制;同理 3 位二进制对应 1 位八进制。

二进制 1100 1111 0101
笨办法:先转十进制 3317,再转十六进制 CF5
聪明办法:从右往左每 4 位一组 → 1100 | 1111 | 0101 → C F 5

二进制 110 011 110 101(每 3 位一组)→ 6 3 6 5(O)

整数部分从右往左分组,小数部分从左往右分组,不够的位补 0。

延伸

  • 在代码里转换:C# 用 Convert.ToString(372, 2) 得到 "101110100",Convert.ToInt32("1BC", 16) 得到 444;格式化十六进制可以写 372.ToString("X")。C# 7 起还能直接写二进制字面量 0b1_0111_0100 和十六进制字面量 0x174,下划线只是分隔符。
  • 为什么程序员偏爱十六进制:一个字节正好 8 位,等于两位十六进制,看内存、看报文时一眼就能对上字节边界。PLC 地址、颜色值(#FF8800)、MAC 地址都是这个原因。
  • 八进制几乎只剩一个地方常见:Linux 的文件权限 chmod 755,每一位八进制正好对应 rwx 三个开关。

# 进制 # 二进制

原文首发于 blog.csdn.net