Appearance
第3章 进制转换
🎯 本章学习目标
学完本章,你将能够:
- 理解进制的基本概念:基数、数码、位权
- 掌握 R 进制转十进制的方法:按权展开求和
- 掌握十进制转 R 进制的方法:整数除基取余倒排、小数乘基取整顺排
- 熟练进行二进制与八进制之间的三位一组快速转换
- 熟练进行二进制与十六进制之间的四位一组快速转换
- 掌握八进制与十六进制之间的"二进制桥梁"转换法
- 记住十六进制数码 A~F 与十进制 10~15 的对应关系
- 理解 C++ 中不同进制的字面量表示(0b/0/0x 前缀)
- 掌握 C++ 中 dec/oct/hex 控制符与 bitset 的使用
- 能够快速比较不同进制数的大小(统一转十进制法)
🗺️ 本章知识图谱
进制转换
├── 基本概念
│ ├── 基数(逢几进一)
│ ├── 数码(允许使用的符号)
│ └── 位权(基数的位次方)
├── 四种进制
│ ├── 二进制(B):0、1,基数2
│ ├── 八进制(O):0~7,基数8
│ ├── 十进制(D):0~9,基数10
│ └── 十六进制(H):0~9、A~F,基数16
├── R进制 → 十进制
│ └── 按权展开求和
│ ├── 整数部分:从右往左,位权 R^0, R^1, R^2...
│ └── 小数部分:从左往右,位权 R^-1, R^-2...
├── 十进制 → R进制
│ ├── 整数部分:除基取余,倒序排列
│ └── 小数部分:乘基取整,顺序排列
├── 二进制 ↔ 八进制
│ ├── 三位一组
│ ├── 二进制→八进制:从右往左每3位一组,左边补0
│ └── 八进制→二进制:每位展开成3位
├── 二进制 ↔ 十六进制
│ ├── 四位一组
│ ├── 二进制→十六进制:从右往左每4位一组,左边补0
│ └── 十六进制→二进制:每位展开成4位
├── 八进制 ↔ 十六进制
│ └── 以二进制为桥梁
└── C++ 中的进制
├── 字面量前缀:0b(二进制)、0(八进制)、0x(十六进制)
├── 输出控制:dec、oct、hex(持久生效)
└── bitset:查看二进制一、进制的基本概念
1.1 什么是进制?
进制(数制)是用固定的符号和统一的规则来表示数值的方法。我们日常使用十进制,计算机内部使用二进制,而八进制、十六进制则是程序员为了简写二进制而发明的"辅助进制"。
理解任何一种进制,只需要抓住三个核心概念:
| 概念 | 含义 | 十进制举例 |
|---|---|---|
| 基数(Base) | 该进制使用的数码个数,逢几进一就是几进制 | 十进制基数为 10 |
| 数码(Digit) | 该进制中允许使用的基本符号 | 0、1、2 …… 9 |
| 位权(Weight) | 每个数位上的数码所代表的实际数值大小 = 数码 × 基数的位次方 | 百位上的 3 表示 3×10²=300 |
高频考点 🔥: 位权是进制转换的灵魂!小数点左边第 i 位(从 0 开始数)的位权是 R^i,小数点右边第 j 位的位权是 R^(-j)。
1.2 四种进制对照表
| 进制 | 基数 | 数码 | 进位规则 | 书写标识 | C++前缀 |
|---|---|---|---|---|---|
| 二进制 | 2 | 0、1 | 逢二进一 | (1011)₂ 或 1011B | 0b1011 |
| 八进制 | 8 | 0~7 | 逢八进一 | (157)₈ 或 157O | 017 |
| 十进制 | 10 | 0~9 | 逢十进一 | (255)₁₀ 或 255D | 255(无前缀) |
| 十六进制 | 16 | 0~9、A~F | 逢十六进一 | (2AF)₁₆ 或 2AFH | 0x2AF |
易错点 ⚠️: 十六进制中 A~F(不分大小写)分别对应 10~15:A=10、B=11、C=12、D=13、E=14、F=15。这是每年必背的对应关系,记错一个全盘皆错!
| 十六进制数码 | A | B | C | D | E | F |
|---|---|---|---|---|---|---|
| 对应十进制 | 10 | 11 | 12 | 13 | 14 | 15 |
为什么需要八进制和十六进制? 因为 8=2³、16=2⁴,八进制一位正好对应二进制三位,十六进制一位正好对应二进制四位。用它们书写二进制数特别简短——32 位二进制数只需 8 个十六进制位就能写完。
二、R进制 → 十进制:按位权展开求和
2.1 转换方法
把 R 进制数的每一位数码乘以它所在位的位权,再全部相加,得到的就是十进制数。
公式:
(dₙ…d₁d₀.d₋₁d₋₂…)_R = dₙ×Rⁿ + … + d₁×R¹ + d₀×R⁰ + d₋₁×R⁻¹ + d₋₂×R⁻² + …2.2 手算例题
例1:二进制 (1011)₂ 转十进制
| 数位 | 1 | 0 | 1 | 1 |
|---|---|---|---|---|
| 位权 | 2³=8 | 2²=4 | 2¹=2 | 2⁰=1 |
| 乘积 | 8 | 0 | 2 | 1 |
求和:8 + 0 + 2 + 1 = 11,即 (1011)₂ = (11)₁₀
例2:八进制 (157)₈ 转十进制
| 数位 | 1 | 5 | 7 |
|---|---|---|---|
| 位权 | 8²=64 | 8¹=8 | 8⁰=1 |
| 乘积 | 64 | 40 | 7 |
求和:64 + 40 + 7 = 111,即 (157)₈ = (111)₁₀
例3:十六进制 (2AF)₁₆ 转十进制
| 数位 | 2 | A(=10) | F(=15) |
|---|---|---|---|
| 位权 | 16²=256 | 16¹=16 | 16⁰=1 |
| 乘积 | 512 | 160 | 15 |
求和:512 + 160 + 15 = 687,即 (2AF)₁₆ = (687)₁₀
例4:带小数的二进制 (101.01)₂ 转十进制
整数部分:1×2² + 0×2¹ + 1×2⁰ = 5 小数部分:0×2⁻¹ + 1×2⁻² = 0 + 0.25 = 0.25
合计:(101.01)₂ = 5.25
例5:十进制 0.8125 转十六进制: 0.8125 × 16 = 13.0 → 整数位 13 → D,结果 (0.D)₁₆。
易错点 ⚠️: 小数点右边第一位的位权是 R⁻¹(如 2⁻¹=0.5),不是 R⁰!很多同学把小数部分也按 1、2、4 去乘,结果必然错误。
三、十进制 → R进制:整数除基取余,小数乘基取整
十进制转其他进制要分整数部分和小数部分分别处理,最后用小数点拼起来。
3.1 整数部分:除基取余,逆序排列
方法口诀:除基取余,直到商为 0,余数从下往上读(倒排)。
例1:十进制 45 转二进制
| 步骤 | 计算 | 商 | 余数 |
|---|---|---|---|
| 1 | 45 ÷ 2 | 22 | 1 |
| 2 | 22 ÷ 2 | 11 | 0 |
| 3 | 11 ÷ 2 | 5 | 1 |
| 4 | 5 ÷ 2 | 2 | 1 |
| 5 | 2 ÷ 2 | 1 | 0 |
| 6 | 1 ÷ 2 | 0 | 1 |
余数从下往上读:1 0 1 1 0 1,即 45 = (101101)₂
验证:32+8+4+1 = 45 ✓
例2:十进制 200 转十六进制
| 步骤 | 计算 | 商 | 余数 |
|---|---|---|---|
| 1 | 200 ÷ 16 | 12 | 8 |
| 2 | 12 ÷ 16 | 0 | 12 → C |
倒排读:C、8,即 200 = (C8)₁₆
验证:12×16 + 8 = 200 ✓
3.2 小数部分:乘基取整,顺序排列
方法口诀:乘基取整,直到小数部分为 0(或达到精度),整数从上往下读(顺排)。
例3:十进制 0.625 转二进制
| 步骤 | 计算 | 取出的整数位 | 当前小数部分 |
|---|---|---|---|
| 1 | 0.625 × 2 = 1.25 | 1 | 0.25 |
| 2 | 0.25 × 2 = 0.5 | 0 | 0.5 |
| 3 | 0.5 × 2 = 1.0 | 1 | 0(结束) |
整数位顺排:1 0 1,即 0.625 = (0.101)₂
验证:0.5 + 0.125 = 0.625 ✓
例4:十进制 13.75 转二进制(整数+小数综合)
- 整数部分:13 ÷2 依次余 1、0、1、1 → 倒排为 1101
- 小数部分:0.75×2=1.5 取 1,0.5×2=1.0 取 1 → 顺排为 11
结果:13.75 = (1101.11)₂
验证:8+4+1 + 0.5+0.25 = 13.75 ✓
高频考点 🔥: 整数转换余数要倒着读,小数转换整数位要顺着读,方向千万别搞反!可以记成"整数倒挂、小数顺流"。
易错点 ⚠️: 并非所有十进制小数都能精确转换成二进制有限小数!例如 0.1 转二进制是 0.0001100110011… 无限循环,这就是浮点数存在精度误差的根本原因。考试中若遇转换不尽的题目,按题目要求保留位数即可。
四、二进制 ↔ 八进制:三位一组
因为 8 = 2³,所以一位八进制数恰好对应三位二进制数。
4.1 数码对照表(必背)
| 八进制 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| 二进制 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
4.2 二进制 → 八进制
方法:以小数点为界,整数部分从右往左每三位一组,小数部分从左往右每三位一组,不足三位的补 0,每组对照转换。
例:(11010.11)₂ 转八进制
分组(整数向左补零、小数向右补零):
整数部分: 11010 → 011 010 (左边不足3位,补1个0)
小数部分: .11 → .110 (右边不足3位,补1个0)
对照转换: 3 2 . 6结果:(11010.11)₂ = (32.6)₈
验证:11010₂ = 26,32₈ = 3×8+2 = 26 ✓;.11₂=0.75,.6₈=6/8=0.75 ✓
4.3 八进制 → 二进制
方法:每位八进制数码展开成对应的三位二进制,再去掉多余的前导零和小数末尾零。
例:(73)₈ 转二进制
7 → 111
3 → 011
拼接:111 011 → (111011)₂验证:73₈ = 7×8+3 = 59;111011₂ = 32+16+8+2+1 = 59 ✓
易错点 ⚠️: 分组方向永远是从小数点向两边分!整数部分从右往左分组(左边补零),小数部分从左往右分组(右边补零)。从最左侧开始分组是最典型的错误。
五、二进制 ↔ 十六进制:四位一组
因为 16 = 2⁴,所以一位十六进制数恰好对应四位二进制数。
5.1 数码对照表(必背)
| 十六进制 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| 二进制 | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 |
| 十六进制 | 8 | 9 | A | B | C | D | E | F |
|---|---|---|---|---|---|---|---|---|
| 二进制 | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
5.2 二进制 → 十六进制
方法:以小数点为界,整数部分从右往左每四位一组,小数部分从左往右每四位一组,不足四位补 0。
例:(11010110.101)₂ 转十六进制
整数部分:11010110 → 1101 0110
小数部分:.101 → .1010 (右边补1个0)
对照转换: D 6 . A结果:(11010110.101)₂ = (D6.A)₁₆
验证:D6₁₆ = 13×16+6 = 214;11010110₂ = 128+64+16+4+2 = 214 ✓;.A₁₆ = 10/16 = 0.625 = .101₂ ✓
5.3 十六进制 → 二进制
例:(3F)₁₆ 转二进制
3 → 0011
F → 1111
拼接:0011 1111 → 去掉前导零 → (111111)₂验证:3F₁₆ = 3×16+15 = 63;111111₂ = 32+16+8+4+2+1 = 63 ✓
高频考点 🔥: "八三、十六四"——八进制一位对二进制三位,十六进制一位对二进制四位。补零方向:整数补在左边(高位),小数补在右边(低位)。
六、八进制 ↔ 十六进制:以二进制为桥梁
八进制和十六进制之间没有直接的分组对应关系(3 位一组和 4 位一组对不齐),最稳妥的方法是以二进制为中转站:
八进制 ──(每位展开3位)──> 二进制 ──(每4位分组)──> 十六进制
十六进制 ──(每位展开4位)──> 二进制 ──(每3位分组)──> 八进制例1:(73)₈ 转十六进制
第1步:73₈ → 二进制:7→111,3→011,得 111011
第2步:按4位分组(左边补2个0):0011 1011
第3步:对照:0011=3,1011=B
结果:73₈ = (3B)₁₆ (验证:73₈=59,3B₁₆=3×16+11=59 ✓)例2:(2AF)₁₆ 转八进制
第1步:2AF₁₆ → 二进制:2→0010,A→1010,F→1111,得 001010101111
第2步:按3位分组(左边补1个0):001 010 101 111
第3步:对照:001=1,010=2,101=5,111=7
结果:2AF₁₆ = (1257)₈ (验证:2AF₁₆=687,1257₈=512+128+40+7=687 ✓)进制转换路线总览
| 转换方向 | 方法 |
|---|---|
| R进制 → 十进制 | 按位权展开求和 |
| 十进制 → R进制 | 整数除基取余倒排,小数乘基取整顺排 |
| 二进制 ↔ 八进制 | 三位一组,直接对照 |
| 二进制 ↔ 十六进制 | 四位一组,直接对照 |
| 八进制 ↔ 十六进制 | 先转二进制,再分组转换 |
七、C++ 中的进制表示与输出
7.1 整数字面量的进制前缀
| 写法 | 含义 | 示例值 |
|---|---|---|
123 | 十进制(无前缀) | 123 |
0b1011 | 二进制(C++14 起支持,部分环境需开启 -std=c++14)※虽然 C++14 支持 0b,但为兼容不同考试环境,建议在 GESP 考试中不要使用二进制字面量,改用十六进制或十进制。 | 11 |
017 | 八进制(以数字 0 开头) | 15 |
0x2F | 十六进制(以 0x 开头,x 和字母不区分大小写) | 47 |
易错点 ⚠️: C++ 中整数以
0开头表示八进制!所以019是非法的(八进制没有数码 9),编译会报错。写代码时不要随手在数字前加 0。
7.2 完整示例代码
cpp
#include <iostream>
#include <bitset> // 使用 bitset 查看二进制需要包含此头文件
using namespace std;
int main() {
// ===== 1. 不同进制的整数字面量 =====
int a = 0b1011; // 二进制字面量,值为 11
int b = 017; // 八进制字面量(数字0开头),值为 15
int c = 0x2F; // 十六进制字面量,值为 47
int d = 47; // 十进制字面量
cout << "a = " << a << endl; // 默认按十进制输出:a = 11
cout << "b = " << b << endl; // b = 15
cout << "c = " << c << endl; // c = 47
// ===== 2. 使用 dec/oct/hex 控制符切换输出进制 =====
cout << dec << d << endl; // 十进制输出:47
cout << oct << d << endl; // 八进制输出:57
cout << hex << d << endl; // 十六进制输出(小写):2f
cout << uppercase << hex << d << endl; // 大写输出:2F
cout << dec; // 控制符会一直生效,记得切回十进制
// ===== 3. 使用 bitset 输出二进制 =====
// bitset<位数>(整数),尖括号中指定二进制位数
cout << bitset<8>(d) << endl; // 8位二进制:00101111
cout << bitset<16>(d) << endl; // 16位二进制:0000000000101111
return 0;
}
/*
程序输出:
a = 11
b = 15
c = 47
47
57
2f
2F
00101111
0000000000101111
*/高频考点 🔥:
dec、oct、hex是持久生效的控制符——设置一次,后面的所有输出都按该进制,直到再次切换。程序阅读题中常在这里设陷阱!另外cin >> hex >> x;也可以按十六进制读取输入。
八、易错点清单
| 序号 | 易错点 | 正确做法 |
|---|---|---|
| 1 | 分组时从数字最左端开始数 | 永远以小数点为界向两边分组 |
| 2 | 分组不足位数时补错位置 | 整数部分补在左边(高位),小数部分补在右边(低位) |
| 3 | A~F 的对应值记混 | A=10、B=11、C=12、D=13、E=14、F=15,张口就来 |
| 4 | 小数部分位权按 1、2、4 算 | 小数点后位权是 R⁻¹、R⁻²…(0.5、0.25…) |
| 5 | 除基取余后从上往下读余数 | 整数余数倒排(从下往上) |
| 6 | 乘基取整后从下往上读 | 小数整数位顺排(从上往下) |
| 7 | 八进制三位、十六进制四位记反 | "八三、十六四" |
| 8 | C++ 中写 019 之类的数 | 0 开头是八进制,只能出现 0~7 |
| 9 | 八进制↔十六进制硬转 | 一律走二进制桥梁,又快又准 |
| 10 | 认为所有小数都能精确转换 | 如 0.1 转二进制为无限循环小数 |
九、📝 实战练习
练习题 1(单选题)
题目: 下列四个数中,数值最大的是( )
A. (10110110)₂ B. (265)₈ C. 180 D. (B7)₁₆
🔑 点击查看答案与解析
答案: D
解析: 比较不同进制数的大小,统一转换成十进制再比较:
- A:(10110110)₂ = 128 + 32 + 16 + 4 + 2 = 182
- B:(265)₈ = 2×64 + 6×8 + 5 = 128 + 48 + 5 = 181
- C:180
- D:(B7)₁₆ = 11×16 + 7 = 176 + 7 = 183
183 > 182 > 181 > 180,最大的是 D。
解题技巧: 选择题中比较大小,也可以走二进制桥梁快速互转,但位权展开法最稳妥、不易出错。
练习题 2(单选题)
题目: 十进制数 156 转换为二进制是( ),转换为十六进制是( )。
🔑 点击查看答案与解析
答案: (10011100)₂;(9C)₁₆
解析:
(1)除基取余转二进制:
| 步骤 | 计算 | 商 | 余数 |
|---|---|---|---|
| 1 | 156 ÷ 2 | 78 | 0 |
| 2 | 78 ÷ 2 | 39 | 0 |
| 3 | 39 ÷ 2 | 19 | 1 |
| 4 | 19 ÷ 2 | 9 | 1 |
| 5 | 9 ÷ 2 | 4 | 1 |
| 6 | 4 ÷ 2 | 2 | 0 |
| 7 | 2 ÷ 2 | 1 | 0 |
| 8 | 1 ÷ 2 | 0 | 1 |
余数倒排:10011100
(2)转十六进制(两种方法互相验证):
方法一:除基取余——156 ÷ 16 = 9 余 12(C),9 ÷ 16 = 0 余 9,倒排得 9C
方法二:二进制四位分组——1001 1100 → 1001=9,1100=C → 9C ✓
验证:9×16 + 12 = 144 + 12 = 156 ✓
练习题 3(单选题)
题目: 八进制数 (327)₈ 转换为十六进制是( )
A. (D7)₁₆ B. (7D)₁₆ C. (E7)₁₆ D. (D3)₁₆
🔑 点击查看答案与解析
答案: A
解析: 走"八进制 → 二进制 → 十六进制"路线:
第1步:每位八进制展开为三位二进制:
3 → 011,2 → 010,7 → 111
拼接得:011010111第2步:以小数点为界(本题无小数),从右往左每四位一组,左边补零:
011010111 共9位,补3个0凑成12位:
0000 1101 0111第3步:每组对照十六进制:
- 0000 → 0(前导零省略)
- 1101 → 13 → D
- 0111 → 7
结果为 (D7)₁₆,选 A。
验证:327₈ = 3×64 + 2×8 + 7 = 215;D7₁₆ = 13×16 + 7 = 215 ✓
易错提醒: 本题最典型的错误是分组方向搞反,把
011 010 111错误地按"0110、1011、1……"分组。记住:分组永远从右往左、凑不齐在左边补零。
练习题 4(填空题)
题目: 填空:
(1) 八进制的基数是 ______,数码范围是 ______。 (2) 十六进制数码 C 对应的十进制值是 ______。 (3) 二进制数 101.01 的整数部分最高位的位权是 ______,小数部分第一位的位权是 ______。 (4) C++ 中,八进制数以 ______ 开头,十六进制数以 ______ 开头。
🔑 点击查看答案与解析
答案: (1) 8、0~7 (2) 12 (3) 2²(或 4)、2⁻¹(或 0.5) (4) 数字 0、0x(或 0X)
解析:
- (1) 八进制基数为 8,数码为 0、1、2、3、4、5、6、7,逢八进一。
- (2) A=10, B=11, C=12, D=13, E=14, F=15。C 是第 3 个字母,对应 10+2=12。
- (3) 整数部分从右往左位权依次是 2⁰, 2¹, 2²...,
101最高位(最左)是第 2 位(从 0 开始数),位权是 2²=4。小数部分从左往右位权是 2⁻¹, 2⁻²...,第一位是 2⁻¹=0.5。 - (4) C++ 中以 0 开头的整数是八进制(如 017),以 0x 开头的是十六进制(如 0x1F)。
练习题 5(判断题)
题目: 判断下列说法是否正确,正确打"√",错误打"×"。
(1) 八进制数中可以出现数码 8。( ) (2) 十进制整数转二进制,用"除 2 取余,余数从下往上读"。( ) (3) 二进制转八进制时,整数部分从左往右每 3 位一组。( ) (4) 所有十进制小数都能精确转换成有限位二进制小数。( ) (5) C++ 中 cout << hex << 15; 输出 f(小写)。( ) (6) dec、oct、hex 控制符只对下一次输出生效。( )
🔑 点击查看答案与解析
答案: (1) × (2) √ (3) × (4) × (5) √ (6) ×
解析:
- (1) ×:八进制数码只有 0~7,出现 8 就是非法数。
- (2) √:除基取余,逆序排列(余数从下往上读)。
- (3) ×:整数部分从右往左每 3 位一组,不足在左边补 0。从左往右分会导致位数不对齐。
- (4) ×:如 0.1 转二进制是无限循环小数,这正是浮点数存在精度误差的原因。
- (5) √:默认 hex 输出小写字母;加
uppercase后输出大写。 - (6) ×:dec/oct/hex 是持久生效的,设置一次后所有后续输出都受影响,直到切换回来。
练习题 6(单选题)
题目: 以下 C++ 程序的输出是( )
cpp
#include <iostream>
using namespace std;
int main() {
int x = 26;
cout << hex << x << " ";
cout << x << " ";
cout << oct << x << endl;
return 0;
}A. 1a 1a 32 B. 1a 26 32 C. 26 26 32 D. 1a 26 26
🔑 点击查看答案与解析
答案: A
解析: 本题考查进制控制符的"持久生效"特性。
- 第 1 个输出:
hex后输出 26 → 26 的十六进制是1a(16+10=26,10=a) - 第 2 个输出:因为
hex持久生效,仍然按十六进制输出 →1a - 第 3 个输出:切换到
oct后输出 26 → 26 的八进制是32(3×8+2=26)
所以输出是 1a 1a 32,选 A。
⚠️ 易错提醒:很多同学以为第二个
cout << x会回到十进制输出 26,错!进制控制符一旦设置就一直有效,直到被显式切换。考试常在这种地方设陷阱。
练习题 7(单选题)
题目: 下列各数中,与二进制数 101010 值相等的是( )
① (52)₈ ② 42 ③ (2A)₁₆ ④ (101001)₂
A. ①② B. ②③ C. ①②③ D. ①②③④
🔑 点击查看答案与解析
答案: C
解析: 先把二进制 101010 转十进制:
101010 = 32 + 8 + 2 = 42
再逐一验证:
- ①
(52)₈ = 5×8 + 2 = 42✅ 相等 - ②
42✅ 相等 - ③
(2A)₁₆ = 2×16 + 10 = 32 + 10 = 42✅ 相等 - ④
(101001)₂ = 32 + 8 + 1 = 41❌ 不相等
①②③ 都等于 42,选 C。
💡 快速验证技巧:二进制和十六进制可以直接四位一组对照验证:
10 1010→ 补零为0010 1010→2 A→2A,和③一致 ✓
练习题 8(编程题)
题目: 输入一个十进制正整数 n(n ≤ 1000),输出它的二进制表示。
输入样例:
13输出样例:
1101🔑 点击查看答案与解析
C++ 参考代码(方法一:数组存余数倒序输出):
cpp
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int bin[32]; // 存二进制各位(最多32位)
int len = 0; // 二进制位数
// 除基取余
while (n > 0) {
bin[len] = n % 2;
n = n / 2;
len++;
}
// 倒序输出(从高位到低位)
for (int i = len - 1; i >= 0; i--) {
cout << bin[i];
}
cout << endl;
return 0;
}C++ 参考代码(方法二:直接用 bitset,更简洁):
cpp
#include <iostream>
#include <bitset>
using namespace std;
int main() {
int n;
cin >> n;
// 用 bitset 输出二进制,但前面会有前导零
string s = bitset<32>(n).to_string();
// 去掉前导零
int start = 0;
while (start < 31 && s[start] == '0') start++;
cout << s.substr(start) << endl;
return 0;
}解析:
- 方法一是手算思路的代码实现:用数组存每次除以 2 的余数,因为余数是从低位到高位得到的,所以输出时要倒过来输出。
- 方法二利用 C++ 标准库的
bitset直接转成二进制字符串,然后去掉前导零。代码更简洁,但需要了解 bitset 的用法。
验证:13 ÷ 2 余 1, 商 6 → 6 ÷ 2 余 0, 商 3 → 3 ÷ 2 余 1, 商 1 → 1 ÷ 2 余 1, 商 0 余数倒排:1101 ✓
考点:除基取余 + 倒序输出。这是进制转换最经典的编程题。
十、📊 考点总结表
| 考点 | 重要程度 | 出题形式 | 易错点 |
|---|---|---|---|
| 基数、数码、位权的概念 | ⭐⭐⭐ | 选择/判断 | 小数部分位权搞反(以为第一位是 R⁰) |
| R进制转十进制(位权展开) | ⭐⭐⭐⭐ | 选择/计算 | 位权算错;A~F 对应值记错 |
| 十进制转R进制(除基取余/乘基取整) | ⭐⭐⭐⭐⭐ | 选择/填空/计算 | 整数余数从上往下读(应该倒着读);小数整数位从下往上读(应该顺着读) |
| 二进制↔八进制(三位一组) | ⭐⭐⭐⭐ | 选择/填空 | 分组方向搞反(从左往右分);补零位置错(整数补右边) |
| 二进制↔十六进制(四位一组) | ⭐⭐⭐⭐⭐ | 选择/填空 | 三位一组和四位一组记混;A~F 值记混 |
| 八进制↔十六进制(二进制桥梁) | ⭐⭐⭐⭐ | 选择/计算 | 直接硬转不用桥梁;分组方向错 |
| C++ 进制前缀(0/0x)与 dec/oct/hex | ⭐⭐⭐⭐ | 程序阅读/选择 | 以为 0 开头是十进制;不知道控制符持久生效 |
| A~F 对应 10~15 | ⭐⭐⭐⭐⭐ | 各类题型 | 把 A 记成 11、F 记成 16 等偏移错误 |
| 不同进制数的大小比较 | ⭐⭐⭐⭐⭐ | 选择题必考题 | 不转换直接凭感觉比;转换计算出错 |
| 小数转换精度问题 | ⭐⭐⭐ | 判断/选择 | 以为所有小数都能精确转换 |
⭐ 必背速记卡
┌──────────────────────────────────────────────────────┐
│ ⭐ 进制转换必背速记卡 │
├──────────────────────────────────────────────────────┤
│ 1. 进制三要素:基数、数码、位权 │
│ 2. 十六进制 A=10 B=11 C=12 D=13 E=14 F=15 │
│ 3. R→十:按权展开求和(整数从右 R^0起,小数从左 R^-1起) │
│ 4. 十→R:整数除基取余倒排;小数乘基取整顺排 │
│ 5. 八三、十六四:八进制1位=二进制3位,十六1位=4位 │
│ 6. 分组方向:以小数点为界,整数从右往左,小数从左往右 │
│ 7. 补零方向:整数补左边(高位),小数补右边(低位) │
│ 8. 八↔十六:先转二进制当桥梁,再分组转换 │
│ 9. C++中:0开头是八进制,0x开头是十六进制 │
│ 10. dec/oct/hex 持久生效,用了hex记得切回dec │
│ 11. 比较不同进制大小:统一转十进制最稳妥 │
│ 12. 0.1转二进制是无限循环小数,浮点数有精度误差 │
└──────────────────────────────────────────────────────┘