二进制转十进制(及十六进制):分步详解

二进制转十进制的方法是:把每一位乘以它的位权,再把结果相加。位权是 2 的幂,从右往左依次翻倍:1、2、4、8、16,以此类推。例如,二进制数 1011 等于 1×8 + 0×4 + 1×2 + 1×1 = 8 + 0 + 2 + 1 = 11

免费试用:整数进制转换器 免费使用,无需注册账号。

本文介绍二进制转十进制的两种方法、如何反过来把十进制转二进制、什么是十六进制以及程序员为什么使用它,还有如何不借助计算器在二进制、十六进制和八进制之间转换。下面的每个示例都已用代码验证。阅读时如果想核对自己的数字,可以把它们粘贴到免费的二进制转换器中。

如何读二进制:位权

二进制码是只用 0 和 1 两个符号表示的信息。计算机使用二进制,是因为其电路只有两种状态,比如低电压和高电压。每一个二进制数字称为一个(bit),8 位组成一个字节(byte)。

二进制和十进制一样,是一种位置记数法。在十进制中,每一位的值是其右边一位的 10 倍(个位、十位、百位)。在二进制中,每一位的值是其右边一位的 2 倍:

位置(从右数) 第 8 位 第 7 位 第 6 位 第 5 位 第 4 位 第 3 位 第 2 位 第 1 位
2 的幂 2⁷ 2⁶ 2⁵ 2⁴ 2⁰
位权 128 64 32 16 8 4 2 1

1 表示“计入这个位权”,0 表示“跳过”。

二进制转十进制:分步方法

方法一:位权相加

以二进制数 11010110 为例。在每一位下方写出位权,保留位为 1 的那些,再把它们相加:

1 1 0 1 0 1 1 0
位权 128 64 32 16 8 4 2 1
位 × 位权 128 64 0 16 0 4 2 0

128 + 64 + 16 + 4 + 2 = 214。所以 11010110₂ = 214₁₀。右下角的小数字用于在进制不明确时标明进制。

方法二:乘 2 再加

这种方法不需要表格。从 0 开始,从左到右依次读取每一位:把当前累计值乘以 2,再加上当前这一位。

以 101101 为例:

  1. 0 × 2 + 1 = 1
  2. 1 × 2 + 0 = 2
  3. 2 × 2 + 1 = 5
  4. 5 × 2 + 1 = 11
  5. 11 × 2 + 0 = 22
  6. 22 × 2 + 1 = 45

所以 101101₂ = 45。用方法一验证:32 + 8 + 4 + 1 = 45。

十进制转二进制

除 2 取余法

把数字除以 2,记下余数(0 或 1),再用商重复这一过程,直到商为 0。然后从下往上读取余数。以 156 为例:

除法 余数
156 ÷ 2 78 0
78 ÷ 2 39 0
39 ÷ 2 19 1
19 ÷ 2 9 1
9 ÷ 2 4 1
4 ÷ 2 2 0
2 ÷ 2 1 0
1 ÷ 2 0 1

从下往上读,得到 156 = 10011100₂。验证:128 + 16 + 8 + 4 = 156。最常见的错误是从上往下读余数,这样得到的位顺序正好相反。

减去 2 的幂

对于较小的数,更快的做法往往是取不超过它的最大 2 的幂,减去后重复。以 100 为例:先取 64(100 − 64 = 36),然后是 32(36 − 32 = 4),再是 4(4 − 4 = 0)。在 64、32 和 4 下方写 1,其余位置写 0:100 = 1100100₂

什么是十六进制?

十六进制(hex)是以 16 为基数的进制。它需要 16 个数字,所以在 0–9 之后用字母 A–F 表示 10 到 15:A = 10,B = 11,C = 12,D = 13,E = 14,F = 15。每一位的值是其右边一位的 16 倍:1、16、256、4,096,以此类推。

程序员使用十六进制,是因为它与二进制严格对应。四个位有 16 种可能的组合(0000 到 1111),所以一个十六进制数字正好是 4 位两个十六进制数字正好是一个字节。最大的字节 11111111 在十六进制中就是 FF,而在十进制中是 255,从这个数看不出位模式。这就是内存地址、颜色代码、MAC 地址和 IPv6 地址都用十六进制书写的原因。

十六进制转十进制

使用同样的位权法,只是换成 16 的幂,并把字母替换为对应的值:

十进制转十六进制

十进制转十六进制与十进制转二进制的做法相同,只是改为除以 16。10 到 15 的余数写成字母 A 到 F。以 1000 为例:

除法 余数
1000 ÷ 16 62 8
62 ÷ 16 3 14 = E
3 ÷ 16 0 3

从下往上读余数,得到 1000 = 3E8₁₆。验证:3 × 256 + 14 × 16 + 8 = 768 + 224 + 8 = 1000。

二进制转十六进制:每四位一组

由于一个十六进制数字就是四位,二进制转十六进制完全不需要计算。从右边开始,把二进制数每四位分成一组(称为半字节,nibble),再按下表替换每一组:

二进制 十六进制 十进制 二进制 十六进制 十进制
0000 0 0 1000 8 8
0001 1 1 1001 9 9
0010 2 2 1010 A 10
0011 3 3 1011 B 11
0100 4 4 1100 C 12
0101 5 5 1101 D 13
0110 6 6 1110 E 14
0111 7 7 1111 F 15

示例:

十六进制转二进制则反过来:把每个十六进制数字替换为对应的四位。3E8 → 0011 1110 1000 → 去掉前导零后为 1111101000。

八进制简介

八进制以 8 为基数,使用数字 0–7。它的原理与十六进制相同,只是三位一组,因为 2³ = 8。如今它最常见的用途是 Unix 文件权限。在 chmod 755 中,每个数字代表三个权限位(读、写、执行):

所以八进制的 755 对应位模式 111 101 101,即十进制的 493。Chmod 计算器可以把勾选的权限转换成八进制数,也可以显示 755 这样的数字设置了哪些权限。

这些转换在哪里会用到

前缀:0b、0x 和 0o

在代码中,前缀告诉编译器一个数字字面量使用哪种进制:

前缀 进制 示例 十进制值
0b 二进制(2) 0b1011 11
0o 八进制(8) 0o755 493
0x 十六进制(16) 0x3E8 1000

0x 几乎适用于所有语言。Python、JavaScript、Java、C# 和 C++ 都支持 0b。Python 和 JavaScript 使用 0o,而 C 和 C++ 只用一个前导零表示八进制,所以 C 中的 0755 是 493,而不是 755。

大多数语言也能帮你转换字符串:

# Python
int("1011", 2)      # 11
bin(156)            # '0b10011100'
hex(1000)           # '0x3e8'
int("3E8", 16)      # 1000

// JavaScript
parseInt("1011", 2)     // 11
(1000).toString(16)     // "3e8"
Number("0b1011")        // 11

有一个陷阱:在 JavaScript 中,parseInt("0b1011") 返回 0,因为 parseInt 遇到第一个无法识别的字符就会停止,而且它不认识 0b 前缀。应去掉前缀并传入基数(radix),详见 MDN 的 parseInt 参考文档

关于负数

计算机通常用补码(two's complement)存储负整数。要用 8 位表示 −5,先从 5 = 00000101 开始,把每一位取反得到 11111010,再加 1:11111011。如果按无符号数读取,同一个位模式是 251(256 − 5),即十六进制的 FB。这就是为什么同一个字节既可以表示 −5,也可以表示 251,取决于程序是否把它当作有符号数。

二进制、十进制、八进制和十六进制对照表

十进制 二进制 八进制 十六进制
0 0 0 0
1 1 1 1
2 10 2 2
3 11 3 3
4 100 4 4
5 101 5 5
6 110 6 6
7 111 7 7
8 1000 10 8
9 1001 11 9
10 1010 12 A
11 1011 13 B
12 1100 14 C
13 1101 15 D
14 1110 16 E
15 1111 17 F
16 10000 20 10
32 100000 40 20
64 1000000 100 40
100 1100100 144 64
127 1111111 177 7F
128 10000000 200 80
255 11111111 377 FF
256 100000000 400 100

用二进制转换器转换任意进制

免费的二进制转换器直接在浏览器中运行。输入一个数字并设置它的进制,即可同时看到该值的二进制、八进制、十进制和十六进制形式,外加一个自定义输出进制。

需要了解的几点限制:它只转换非负整数,所以负号或小数点会被拒绝;十六进制输出为小写且不带前导零;“Base64 (64)” 这一行是使用数字 0–9、a–z、A–Z、+ 和 / 的 64 进制数,而不是 Base64 文本编码。

常见问题

8 位最多能存储多大的数?

255,二进制写作 11111111,十六进制写作 FF。八位共有 2⁸ = 256 种不同组合,覆盖 0 到 255。十六位可达 65,535,每多一位,范围就翻一倍。

为什么程序员用十六进制而不是十进制?

因为每个十六进制数字正好对应四位,可以直接从十六进制数字读出位模式。一个字节总是两个十六进制数字(00 到 FF)。十进制没有这种对应关系:255 和 256 在十进制中看起来相近,但在二进制中分别是 11111111 和 100000000。

如何把二进制小数转换为十进制?

二进制小数点后的各位分别代表 1/2、1/4、1/8,以此类推。所以 101.11₂ = 4 + 1 + 0.5 + 0.25 = 5.75。许多十进制小数(例如 0.1)没有精确的二进制表示,这就是为什么在大多数编程语言中 0.1 + 0.2 并不严格等于 0.3。二进制转换器只处理整数。

二进制码和 ASCII 是一回事吗?

不是。二进制是一种数制;ASCII 是一张为每个字符分配编号的表。字母 A 的 ASCII 码是 65,这个数字以位 01000001 的形式存储。

免费试用:整数进制转换器 免费使用,无需注册账号。