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

二进制转十进制的方法是:把每一位乘以它的位权,再把结果相加。位权是 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³2²2¹2⁰
位权1286432168421

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

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

方法一:位权相加

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

位11010110
位权1286432168421
位 × 位权128640160420

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 ÷ 2780
78 ÷ 2390
39 ÷ 2191
19 ÷ 291
9 ÷ 241
4 ÷ 220
2 ÷ 210
1 ÷ 201

从下往上读,得到 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 ÷ 16628
62 ÷ 16314 = E
3 ÷ 1603

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

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

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

二进制十六进制十进制二进制十六进制十进制
000000100088
000111100199
0010221010A10
0011331011B11
0100441100C12
0101551101D13
0110661110E14
0111771111F15

示例:

十六进制转二进制则反过来:把每个十六进制数字替换为对应的四位。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)0b101111
0o八进制(8)0o755493
0x十六进制(16)0x3E81000

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,取决于程序是否把它当作有符号数。

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

十进制二进制八进制十六进制
0000
1111
21022
31133
410044
510155
611066
711177
81000108
91001119
10101012A
11101113B
12110014C
13110115D
14111016E
15111117F
16100002010
321000004020
64100000010040
100110010014464
12711111111777F
1281000000020080
25511111111377FF
256100000000400100

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

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

需要了解的几点限制:它只转换非负整数,所以负号或小数点会被拒绝;十六进制输出为小写且不带前导零;“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 的形式存储。

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