计算机对数据的表示(数制)
1. 什么是数制
数制,也称为进位计数制,是一种计数方法。它使用有限的数字符号和固定的进位规则来表示数值。
1.1 进制的核心要素
- 基数(Base):进制中使用的数字符号的个数。例如,二进制的基数是 2,十进制的基数是 10。
- 位权(Positional Weight):每个位置上的数字所代表的权重,等于基数的幂次。例如,在十进制中,个位的位权是 10⁰=1,十位的位权是 10¹=10。
- 进位规则:当某一位达到基数时,向高位进 1。例如,在十进制中,9 的下一位是 10。
1.2 常见进制系统
| 进制 | 基数 | 数字符号 | 表示方法 | 示例 |
|---|---|---|---|---|
| 二进制 | 2 | 0, 1 | 0b 或 0B 开头 | 0b1010 |
| 八进制 | 8 | 0-7 | 0 开头 | 017 |
| 十进制 | 10 | 0-9 | 直接表示 | 42 |
| 十六进制 | 16 | 0-9, A-F | 0x 或 0X 开头 | 0xFF |
1.3 进制表示示例
二进制:1010₂ = 0b1010
八进制:123₈ = 017
十进制:456₁₀ = 456(通常省略下标)
十六进制:ABC₁₆ = 0xABC
2. 进制的作用
2.1 在计算机中的基础作用
二进制是计算机的基础:
- 计算机硬件本质上是电子电路,只有两种稳定状态:开(1)和关(0)
- 所有数据在计算机内部都以二进制形式存储和处理
- 二进制是计算机能够理解和处理数据的唯一方式
2.2 不同进制的应用场景
二进制(Binary):
- 计算机内部数据存储和处理
- 位运算和逻辑运算
- 硬件电路设计
八进制(Octal):
- Unix/Linux 文件权限表示(如 755、644)
- 历史遗留系统(现在较少使用)
十进制(Decimal):
- 人类日常计数和计算
- 用户界面显示
- 大多数编程语言的默认数字表示
十六进制(Hexadecimal):
- 内存地址表示
- 颜色值表示(RGB,如 #FF5733)
- 调试信息和内存转储
- 网络协议数据包
- 文件格式分析
2.3 为什么需要多种进制?
- 二进制:计算机硬件的基础,但人类难以阅读
- 十进制:人类最熟悉,但不适合计算机直接处理
- 十六进制:介于两者之间,既便于人类阅读,又与二进制转换简单(1 位十六进制 = 4 位二进制)
3. 进制转换
3.1 进制转换速查表(0-15)
| 十进制 | 二进制 | 八进制 | 十六进制 |
|---|---|---|---|
| 0 | 0000 | 0 | 0 |
| 1 | 0001 | 1 | 1 |
| 2 | 0010 | 2 | 2 |
| 3 | 0011 | 3 | 3 |
| 4 | 0100 | 4 | 4 |
| 5 | 0101 | 5 | 5 |
| 6 | 0110 | 6 | 6 |
| 7 | 0111 | 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 |
3.2 十进制转其他进制(除基取余法)
原理:不断用目标进制的基数去除十进制数,记录余数,直到商为 0,然后将余数倒序排列。
示例 1:将 25₁₀ 转换为二进制
25 ÷ 2 = 12 ... 余 1 ↑
12 ÷ 2 = 6 ... 余 0 │
6 ÷ 2 = 3 ... 余 0 │ 倒序排列
3 ÷ 2 = 1 ... 余 1 │
1 ÷ 2 = 0 ... 余 1 │
结果:25₁₀ = 11001₂
示例 2:将 100₁₀ 转换为二进制
100 ÷ 2 = 50 ... 余 0 ↑
50 ÷ 2 = 25 ... 余 0 │
25 ÷ 2 = 12 ... 余 1 │
12 ÷ 2 = 6 ... 余 0 │ 倒序排列
6 ÷ 2 = 3 ... 余 0 │
3 ÷ 2 = 1 ... 余 1 │
1 ÷ 2 = 0 ... 余 1 │
结果:100₁₀ = 1100100₂
示例:将 100₁₀ 转换为八进制
100 ÷ 8 = 12 ... 余 4 ↑
12 ÷ 8 = 1 ... 余 4 │ 倒序排列
1 ÷ 8 = 0 ... 余 1 │
结果:100₁₀ = 144₈
示例:将 255₁₀ 转换为十六进制
255 ÷ 16 = 15 ... 余 15 (F) ↑
15 ÷ 16 = 0 ... 余 15 (F) │ 倒序排列
结果:255₁₀ = FF₁₆
示例 2:将 100₁₀ 转换为十六进制
100 ÷ 16 = 6 ... 余 4 ↑
6 ÷ 16 = 0 ... 余 6 │ 倒序排列
结果:100₁₀ = 64₁₆
3.3 其他进制转十进制(按权展开法)
原理:每一位数字乘以基数的相应幂次,然后求和。
示例:将 11001₂ 转换为十进制
位置: 4 3 2 1 0
数值: 1 1 0 0 1
计算:
1 × 2⁴ = 1 × 16 = 16
1 × 2³ = 1 × 8 = 8
0 × 2² = 0 × 4 = 0
0 × 2¹ = 0 × 2 = 0
1 × 2⁰ = 1 × 1 = 1
────────────────────
总和: 25
结果:11001₂ = 25₁₀
示例:将 3A5₁₆ 转换为十进制
3 × 16² = 3 × 256 = 768
A × 16¹ = 10 × 16 = 160
5 × 16⁰ = 5 × 1 = 5
────────────────────
总和: 933
结果:3A5₁₆ = 933₁₀
3.4 二进制与十六进制互转(快速转换)
由于 16 = 2⁴,1 位十六进制数对应 4 位二进制数,转换非常简单。
二进制转十六进制:
- 从右到左,每 4 位为一组
- 不足 4 位时,左边补 0
- 每组转换为对应的十六进制数字
示例:将 1101011011₂ 转换为十六进制
分组: 0011 0101 1011
转换: 3 5 B
结果:1101011011₂ = 35B₁₆
十六进制转二进制:
- 每一位十六进制数转换为 4 位二进制数
- 直接拼接即可
示例:将 3A5₁₆ 转换为二进制
3 → 0011
A → 1010
5 → 0101
结果:3A5₁₆ = 001110100101₂ = 1110100101₂
3.4.1 补位详解
什么是补位?
补位(Padding)是指在二进制数的左边添加 0,使其达到指定的位数。补位不改变数值的大小,只是改变了表示形式。
为什么需要补位?
分组转换的需要:
- 二进制转十六进制时,需要每 4 位一组
- 二进制转八进制时,需要每 3 位一组
- 如果二进制数的位数不是 4 或 3 的倍数,最左边的一组会不足位数,需要补 0
计算机存储的需要:
- 计算机按固定位数(如 8 位、16 位、32 位)存储数据
- 如果数据位数不足,需要在左边补 0 到指定位数
对齐的需要:
- 内存对齐要求数据按特定字节边界存储
- 需要补位到对齐边界
补位示例:
示例 1:二进制转十六进制时的补位
将 1101011011₂ 转换为十六进制:
- 原始二进制:
1101011011(10 位) - 从右到左分组:
1101011011 - 最左边一组只有 2 位,需要补 0 到 4 位:
0011 - 补位后分组:
001101011011 - 转换结果:
35B₁₆
示例 2:按字节(8 位)补位
将 11001₂(5 位)按字节存储:
- 原始:
11001(5 位) - 补位到 8 位:
00011001(8 位) - 数值不变:都是 25₁₀
示例 3:二进制转八进制时的补位
将 1011011₂ 转换为八进制:
- 原始二进制:
1011011(7 位) - 从右到左分组:
1011011 - 最左边一组只有 1 位,需要补 0 到 3 位:
001 - 补位后分组:
001011011 - 转换结果:
133₈
补位的规则:
- 补位位置:总是在左边(高位)补 0
- 补位数量:补到目标位数的整数倍
- 转十六进制:补到 4 的倍数
- 转八进制:补到 3 的倍数
- 按字节存储:补到 8 的倍数
- 数值不变:补位不改变数值,
11001₂ = 00011001₂ = 25₁₀
注意事项:
- 补位只在左边补 0,不在右边补
- 补位不改变数值大小
- 在进制转换中,补位是为了方便分组
- 在计算机存储中,补位是为了满足固定位数的要求
3.5 二进制与八进制互转
由于 8 = 2³,1 位八进制数对应 3 位二进制数。
二进制转八进制:每 3 位一组转换 八进制转二进制:每位转 3 位二进制
4. 实际应用示例
4.1 内存地址表示
// 内存地址通常用十六进制表示
long address = 0x00007FFF12345678L; // 64位地址
int address16 = 0xFFFF; // 16位地址最大值
4.2 颜色值表示
// RGB 颜色值(十六进制)
int red = 0xFF0000; // 红色
int green = 0x00FF00; // 绿色
int blue = 0x0000FF; // 蓝色
int white = 0xFFFFFF; // 白色
// CSS 颜色格式
String color = "#FF5733"; // 橙红色
4.3 位运算操作
// 位运算示例
int a = 0b1010; // 10
int b = 0b1100; // 12
int and = a & b; // 按位与:0b1000 = 8
int or = a | b; // 按位或:0b1110 = 14
int xor = a ^ b; // 按位异或:0b0110 = 6
int leftShift = a << 1; // 左移:0b10100 = 20
int rightShift = a >> 1; // 右移:0b0101 = 5
4.4 文件权限(Unix/Linux)
// 文件权限用八进制表示
int readWriteExecute = 0777; // rwxrwxrwx
int readWrite = 0666; // rw-rw-rw-
int readOnly = 0444; // r--r--r--
// 权限位说明
// 7 = 4(读) + 2(写) + 1(执行) = rwx
// 6 = 4(读) + 2(写) = rw-
// 5 = 4(读) + 1(执行) = r-x
// 4 = 4(读) = r--
5. 总结
5.1 核心要点
- 进制是计数的基础:不同进制使用不同的基数和数字符号
- 二进制是计算机的母语:所有数据在计算机内部都以二进制形式存储
- 十六进制是二进制的简化:便于人类阅读,同时与二进制转换简单
- 数据存储有固定大小:不同类型的数据占用不同的存储空间
- 进制转换有规律可循:掌握方法后可以快速转换
5.2 关键概念
- 位(Bit):信息的最小单位,0 或 1
- 字节(Byte):8 位,计算机的基本存储单位
- 基数:进制中使用的数字符号个数
- 位权:每个位置上的数字所代表的权重
- 字节序:多字节数据在内存中的存储顺序
理解进制和数据存储对于:
- 深入理解计算机工作原理
- 进行底层编程和优化
- 调试和排查问题
- 理解数据存储和传输
至关重要!
