第21章 计算机的数制
| 等级 | 知识块 | 考查频率 |
|---|---|---|
| GESP C++ 三级 | 进制转换(二 / 八 / 十 / 十六) | ⭐⭐⭐ |
数制(计数制)是用一组固定符号和统一规则表示数值的方法。计算机底层用二进制存储与运算;为了方便书写与阅读,又常用八进制、十六进制;而人类最熟悉的是十进制。本章讲清四种进制的基数、位权,以及它们之间的相互转换。
21.1 数制的基本概念
21.1.1 基数
基数 = 每个数位上可用的符号个数。
- 十进制:基数 10,符号
0~9 - 二进制:基数 2,符号
0、1 - 八进制:基数 8,符号
0~7 - 十六进制:基数 16,符号
0~9、A~F(A=10,B=11,…,F=15)
21.1.2 位权
位权 = 基数的 次方,从右往左、下标从 0 开始。
十进制 123:
21.2 计算机中常用的数制
21.2.1 十进制(Decimal)
后缀 D(可省略);逢十进一、借一当十,日常生活使用。
21.2.2 二进制(Binary)
后缀 B;仅 0、1;逢二进一。是计算机唯一的底层存储格式(晶体管导通/截止对应 1/0)。
- 加法:
- 减法:
21.2.3 八进制(Octal)
后缀 O 或 Q;3 位二进制 = 1 位八进制,用来简化长二进制串的书写。
21.2.4 十六进制(Hexadecimal)
后缀 H;4 位二进制 = 1 位十六进制,编程中最常用(内存地址、颜色值、位运算掩码等),逢十六进一。
一个字节(8 位)用二进制要写 8 个数字,用十六进制只需 2 个(00~FF),既短又好和二进制互转(每 4 位一组)。例如内存地址 0x1A2B 比 0001101000101011 好读得多。
21.3 数制之间的转换
21.3.1 任意进制 → 十进制
规则:按位权展开求和。
- 二进制 :
- 八进制 :
- 十六进制 :
21.3.2 十进制 → 任意进制
- 整数部分:除基取余,逆序输出
- 小数部分:乘基取整,顺序输出(三级一般只考整数)
示例1:十进制 11 → 二进制
11 ÷ 2 = 5 余 1
5 ÷ 2 = 2 余 1
2 ÷ 2 = 1 余 0
1 ÷ 2 = 0 余 1
余数逆序:1011
示例2:十进制 83 → 八进制
83 ÷ 8 = 10 余 3
10 ÷ 8 = 1 余 2
1 ÷ 8 = 0 余 1
逆序得:123
示例3:十进制 419 → 十六进制
419 ÷ 16 = 26 余 3
26 ÷ 16 = 1 余 10(A)
1 ÷ 16 = 0 余 1
逆序得:1A3
21.3.3 二进制 ↔ 八 / 十六进制
- 二进制 → 八进制:从右往左每 3 位一组,不足左补 0。
例: →
101 101→ - 二进制 → 十六进制:每 4 位一组,不足左补 0。
例: →
1011 0101→ - 反过来:八/十六进制转二进制,就是 1 位拆成 3 位 / 4 位,去掉前导 0。
分组必须从右往左(低位开始)每 3/4 位一组,左边不足补 0。写成 010 110 101 这种从左补 0 是错误的,要从右补。例如 101101 应分 101 101 不是 101 10 1。
21.4 C++ 进制与转换示例
C++ 直接支持多种进制字面量,并可用 <bitset> 输出二进制、<iomanip> 控制输出进制。
#include <iostream>
#include <bitset> // 用于二进制输出
#include <iomanip> // 用于 hex / oct 输出
using namespace std;
// 十进制整数转二进制字符串(除 2 取余)
void decToBin(int n) {
if (n == 0) { cout << 0; return; }
int bits[32], k = 0;
int x = n;
while (x > 0) { bits[k++] = x % 2; x /= 2; }
for (int i = k - 1; i >= 0; i--) cout << bits[i];
}
int main() {
int x = 255;
cout << "十进制 " << x << " 的二进制: "
<< bitset<8>(x) << endl; // 11111111
// 字面量与不同进制输出
int a = 0xFF; // 十六进制字面量
int b = 0177; // 八进制字面量(以 0 开头)
cout << "0xFF = " << a << " , 0177 = " << b << endl;
cout << "255 八进制 = " << oct << x << endl; // 377
cout << "255 十六进制 = " << hex << x << endl; // ff
return 0;
}
bitset<8>(255) 输出 11111111;0xFF 即 255,0177 即 127;oct 输出 377,hex 输出 ff。可见 C++ 里进制只是「书写/显示」的差异,底层一律二进制存。
21.5 选择题练习
1. 十六进制数 1A 转换为十进制是?
A. 26
B. 16
C. 10
D. 25
点击展开参考答案与解析
答案:A
解析:,选 A。
2. 将十进制数 100 转换为二进制,结果是?
A. 1100100
B. 1101000
C. 1011100
D. 1110000
点击展开参考答案与解析
答案:A
解析:100 除 2:100→50余0, 50→25余0, 25→12余1, 12→6余0, 6→3余0, 3→1余1, 1→0余1;逆序 1100100,选 A。
3. 二进制数 111010 转换为八进制,结果是?
A. 72
B. 73
C. 71
D. 36
点击展开参考答案与解析
答案:A
解析:111010 从右 3 位分组:111 010 → 7 2 = 72,选 A。
4. 关于二进制与十六进制的转换,下列说法正确的是?
A. 每 3 位二进制对应 1 位十六进制
B. 每 4 位二进制对应 1 位十六进制
C. 每 2 位二进制对应 1 位十六进制
D. 二进制与十六进制无法快速互转
点击展开参考答案与解析
答案:B
解析:4 位二进制 = 1 位十六进制,选 B(3 位对应的是八进制)。
5. C++ 中,八进制字面量的特征是?
A. 以 0x 开头
B. 以 0 开头
C. 以 0b 开头
D. 以 H 结尾
点击展开参考答案与解析
答案:B
解析:C++ 八进制字面量以数字 0 开头(如 0177),0x 是十六进制,0b 是二进制(C++14 起),选 B。