# 进制与进制转换 — 学习笔记

**日期**: 2026/07/10  
**作者**: WanJl

---

## 一、为什么计算机使用二进制

- 计算机由晶体管组成，只有**通电（1）**和**断电（0）**两种状态
- 两种状态最稳定可靠，电路设计最简单
- 如果使用十进制需要10种电压值，电路极其复杂

> 计算机使用二进制不是因为二进制高级，只是因为硬件只识别通电/断电。

---

## 二、四种进制

| 进制 | 基数 | 数字符号 | Java 前缀 |
|------|------|---------|-----------|
| 二进制 | 2 | 0, 1 | `0b` / `0B` |
| 八进制 | 8 | 0~7 | `0` |
| 十进制 | 10 | 0~9 | 正常写 |
| 十六进制 | 16 | 0~9, A~F | `0x` / `0X` |

**十六进制 A~F 对应值**：A=10, B=11, C=12, D=13, E=14, F=15

**编码**：把人能看懂的信息（十进制数、文本、图片等）转换为二进制数据的过程。  
**解码**：编码的逆过程，把二进制数据转换回人能看懂的信息。

---

## 三、二进制 → 十进制（按权展开法）

二进制位权从右往左：`2^0, 2^1, 2^2, 2^3, ...`

**示例**：`1101`（二进制）

| 位 | 1 | 1 | 0 | 1 |
|---|:---:|:---:|:---:|:---:|
| 位权 | 2³=8 | 2²=4 | 2¹=2 | 2⁰=1 |
| 计算 | 1×8 | 1×4 | 0×2 | 1×1 |

结果：`1×8 + 1×4 + 0×2 + 1×1 = 13`（十进制）

---

## 四、八进制 → 二进制 与 十六进制 → 二进制

### 八进制与二进制（3位一组）

```
二进制：   001  101  111
八进制：     1    5    7
```

每 **3** 位二进制对应 **1** 位八进制。

### 十六进制与二进制（4位一组）

```
二进制：    1101  1110  1010  0101
十六进制：    D     E     A     5
```

每 **4** 位二进制对应 **1** 位十六进制。

**十六进制常见用途**：颜色色值、内存地址、MAC 地址、文件权限等。

---

## 五、任意进制 → 十进制（按权展开法）

**方法**：每一位数字 × 位权，再求和。

### 二进制 → 十进制

```
0b1001 → 1×2³ + 0×2² + 0×2¹ + 1×2⁰ = 8 + 0 + 0 + 1 = 9
```

### 八进制 → 十进制

```
0257 → 2×8² + 5×8¹ + 7×8⁰ = 128 + 40 + 7 = 175
```

### 十六进制 → 十进制

```
0x3F → 3×16¹ + 15×16⁰ = 48 + 15 = 63
```

> 对应授课代码：`Demo02.java` — 按权展开法示例

---

## 六、十进制 → 任意进制（除基取余法）

**方法**：不断除以目标进制，取余数，**从下往上**排列余数。

### 十进制 → 二进制（除2取余）

将 25 转换为二进制：

```
25 ÷ 2 = 12 余 1
12 ÷ 2 = 6  余 0
6  ÷ 2 = 3  余 0
3  ÷ 2 = 1  余 1
1  ÷ 2 = 0  余 1
```
从下往上读：**11001**

> 结果：十进制数 25 = 二进制数 11001

### 十进制 → 八进制（除8取余）

将 175 转换为八进制：

```
175 ÷ 8 = 21 余 7
21  ÷ 8 = 2  余 5
2   ÷ 8 = 0  余 2
```
从下往上读：**257**

> 结果：十进制数 175 = 八进制数 257

### 十进制 → 十六进制（除16取余）

将 255 转换为十六进制：

```
255 ÷ 16 = 15 余 15 → F
15  ÷ 16 = 0  余 15 → F
```
从下往上读：**FF**

> 结果：十进制数 255 = 十六进制数 FF

> 对应授课代码：`Demo03.java` — 除基取余法示例

---

## 七、Java 代码示例

```java
int a = 0b0101011;     // 二进制，加前缀 0b
int b = 01234567;      // 八进制，加前缀 0
int c = 0x123AFEC9;    // 十六进制，加前缀 0x

System.out.println(a);  // Java 自动转换为十进制输出
System.out.println(b);
System.out.println(c);
```

> 对应授课代码：`Demo01.java` — 进制基础概念

---

## 八、知识总结

| 知识点 | 要点 |
|-------|------|
| 二进制 | `0b` 前缀，基数 2，符号 0/1 |
| 八进制 | `0` 前缀，基数 8，3位二进制对应1位八进制 |
| 十六进制 | `0x` 前缀，基数 16，4位二进制对应1位十六进制 |
| 按权展开法 | 每位数字 × 位权，再求和 → 得到十进制 |
| 除基取余法 | 不断除以目标进制，取余数从下往上排列 → 得到目标进制 |
| 编码/解码 | 人→机器（编码），机器→人（解码） |

---

## 九、练习题（进制转换）

将十进制数 357 分别转换为二进制、八进制、十六进制：
- 二进制：**101100101**
- 八进制：**545**
- 十六进制：**165**

将十进制数 1234 分别转换为二进制、八进制、十六进制：
- 二进制：**10011010010**
- 八进制：**2322**
- 十六进制：**4D2**

> 答案来自授课代码 `Demo03.java`

---

## 十、ASCII 码表与字符编码

字符在计算机中存储时，本质也是二进制数。ASCII 码表规定了常用字符与整数的对应关系。

| 字符范围 | ASCII 码值 |
|---------|-----------|
| `'0'` ~ `'9'` | 48 ~ 57 |
| `'A'` ~ `'Z'` | 65 ~ 90 |
| `'a'` ~ `'z'` | 97 ~ 122 |

### Java 代码示例

```java
char c2 = 67;   // 对应 'C'
char c3 = 90;   // 对应 'Z'
System.out.println(c2);  // 输出 C
System.out.println(c3);  // 输出 Z

char c1 = 'a';
System.out.println(c1 >= 'A' && c1 <= 'Z');  // false
```

---

## 十一、课堂练习 — 综合复习（Demo04）

`Demo04.java` 涵盖了之前学习的数据类型与运算符的综合练习题：

| 练习 | 知识点 | 代码位置 |
|------|--------|---------|
| 算术运算 | `+ - * / %` | 第19~25行 |
| 判断奇偶 | 三目运算符 `%2==0` | 第27~28行 |
| 求最大值 | 嵌套三目 | 第30行 |
| 判断闰年 | `&&` `||` 逻辑运算符 | 第32~33行 |
| 评分等级 | 嵌套三目 `>=90?A:>=60?B:C` | 第35~36行 |
| 范围判断 | `&&` 判断 10<x<100 | 第38行 |
| ASCII 判断大写字母 | 字符比较 `>=65 && <=90` | 第40~47行 |
| 前置/后置自增 | `++` 前缀与后缀区别 | 第49~55行 |
| 数位拆分 | `%10` `/10%10` `/100` | 第57~63行 |
| 三角形判断 | 两边之和大于第三边 | 第65行 |

---

## 十二、循环结构练习（Demo05 ~ Demo09）

day04 引入循环结构（`for`、`while`），以下是课堂练习题：

| 文件 | 题目 | 核心知识点 |
|------|------|-----------|
| `Demo05.java` | 输出斐波那契数列前10项 | `for` 循环、变量前移 `a=b; b=c` |
| `Demo06.java` | 判断素数 | `for` 循环 + `if` 分支 + `break` |
| `Demo07.java` | 数列求和 1 - 1/2 + 1/3 - ... 前10项 | `for` 循环、正负交替、浮点精度 |
| `Demo08.java` | 判断回文数 | `while` 循环、数位反转 `b=b*10+f` |
| `Demo09.java` | 计算 1!+2!+...+10! | `for` 循环、阶乘累积 `f*=i` |

### Demo05 — 斐波那契数列

第1项为0，第2项为1，从第3项开始每项等于前两项之和。

```java
int a = 0, b = 1;
System.out.println(a);
System.out.println(b);
for (int i = 3; i <= 10; i++) {
    int c = a + b;
    System.out.println(c);
    a = b;
    b = c;
}
```

### Demo06 — 判断素数

素数：大于1的自然数，除了1和它本身外不再有其他因数。

```java
int n = 17;
boolean b = n > 1;
for (int i = 2; i <= n; i++) {
    if (n % i == 0) {
        b = false;
        break;
    }
}
System.out.println(b ? "no" : "yes");
```

### Demo07 — 数列求和（正负交替）

求 1 - 1/2 + 1/3 - 1/4 + ... 前10项的和。

```java
double sum = 0;
for (int i = 1; i <= 10; i++) {
    if (i % 2 == 1) {
        sum += 1.0 / i;   // 奇数项为正
    } else {
        sum -= 1.0 / i;   // 偶数项为负
    }
}
System.out.printf("%.2f", sum);
```

### Demo08 — 判断回文数

回文数：正读和反读都一样的数，如 12321。

```java
int n = 12321;
int a = n;    // 保存原始值
int b = 0;    // 用来存放反转后的数
while (n > 0) {
    int f = n % 10;   // 取出最后一位
    b = b * 10 + f;   // 拼接反转
    n /= 10;          // 去掉最后一位
}
System.out.println(a == b ? "yes" : "no");
```

### Demo09 — 阶乘求和

计算 1! + 2! + 3! + ... + 10! 的值。

```java
int sum = 0;
int f = 1;
for (int i = 1; i <= 10; i++) {
    f *= i;      // 计算当前阶乘
    sum += f;    // 累加
}
System.out.println(sum);
```

---

## 十三、代码索引

| 文件 | 完整路径 |
|------|---------|
| Demo01 | [`Demo01.java`](../../授课代码/java-prep-bootcamp/src/com/lovecoding/day04/Demo01.java) |
| Demo02 | [`Demo02.java`](../../授课代码/java-prep-bootcamp/src/com/lovecoding/day04/Demo02.java) |
| Demo03 | [`Demo03.java`](../../授课代码/java-prep-bootcamp/src/com/lovecoding/day04/Demo03.java) |
| Demo04 | [`Demo04.java`](../../授课代码/java-prep-bootcamp/src/com/lovecoding/day04/Demo04.java) |
| Demo05 | [`Demo05.java`](../../授课代码/java-prep-bootcamp/src/com/lovecoding/day04/Demo05.java) |
| Demo06 | [`Demo06.java`](../../授课代码/java-prep-bootcamp/src/com/lovecoding/day04/Demo06.java) |
| Demo07 | [`Demo07.java`](../../授课代码/java-prep-bootcamp/src/com/lovecoding/day04/Demo07.java) |
| Demo08 | [`Demo08.java`](../../授课代码/java-prep-bootcamp/src/com/lovecoding/day04/Demo08.java) |
| Demo09 | [`Demo09.java`](../../授课代码/java-prep-bootcamp/src/com/lovecoding/day04/Demo09.java) |
