本讲定位:CSP-J 初赛系列的知识重头讲。七年真题统计(见
cspj-exam-analysis-2019-2025.md):进制转换类选择题七年六出;2024、2025 连续两年开卷第 1 题考”32 位 int/unsigned 的取值范围”——数据类型范围已从冷知识变成固定送分题;溢出、char 符号、浮点精度是阅读程序判断题五大陷阱之一”溢出与数据类型”的弹药库(2021 负数补码、2022mid*mid溢出、2023 浮点精度,年年有份)。本讲把”数和字符在机器里长什么样”一次讲透。本讲是下一讲(位运算)的地基:不懂补码,就解释不了
x & -x在负数下的行为;不熟二进制,位运算技巧只能死记。两讲连着学。前置知识:整数四则运算、
%与/运算符。适合对象:CSP-J 初赛。标注 ⭐ 的小节为进阶内容,第一遍学习可以跳过。
$k$ 进制就是”逢 $k$ 进一”:从右往左第 $i$ 位(从 0 数起)的权是 $k^i$。写作 $(a_m \dots a_1 a_0)_k$ 的数,值为
$$ (a_m \dots a_1 a_0)_k = a_m \cdot k^m + \dots + a_1 \cdot k^1 + a_0 \cdot k^0 $$
初赛常用的四种进制与书写习惯:
| 进制 | 数码 | C++ 字面量写法 | 例 |
|---|---|---|---|
| 二进制 | 0, 1 | 0b1100100 |
$(1100100)_2 = 100$ |
| 八进制 | 0~7 | 前导 0:0144 |
$(144)_8 = 100$ |
| 十进制 | 0~9 | 100 |
100 |
| 十六进制 | 0~9, A~F | 0x64 |
$(64)_{16} = 100$ |
十六进制的 A~F 代表 10~15。C++ 里前导 0 的整数是八进制——010 是 8 不是 10,选择题的经典冷箭。
$(2A3)_{16} = 2 \times 256 + 10 \times 16 + 3 = 675$。没有任何技巧,权乘数码求和即可。考场上二进制转十进制建议直接背 2 的幂:$1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024$(背到 $2^{10}$,再记住 $2^{16} = 65536$、$2^{31} \approx 2.1 \times 10^9$ 两个锚点)。
不断除以 $k$、记录余数,直到商为 0,余数从下往上读:
$$ 100 \div 2 = 50 \cdots 0,\quad 50 \div 2 = 25 \cdots 0,\quad 25 \div 2 = 12 \cdots 1,\quad 12 \div 2 = 6 \cdots 0, $$
$$ 6 \div 2 = 3 \cdots 0,\quad 3 \div 2 = 1 \cdots 1,\quad 1 \div 2 = 0 \cdots 1 $$
从下往上:$100 = (1100100)_2$。为什么倒着读?第一次除得到的余数是”个位”(权最小),最后一次是最高位。
小数部分(简要,选择题偶考):乘基取整,正着读。$0.625 \times 2 = 1.25$ 取 1;$0.25 \times 2 = 0.5$ 取 0;$0.5 \times 2 = 1.0$ 取 1——$0.625 = (0.101)_2$。有的十进制小数二进制写不完(见第 5 节浮点数),如 $0.1 = (0.000110011\overline{0011}\dots)_2$ 无限循环。
因为 $8 = 2^3$、$16 = 2^4$,二进制从右往左每 3 位对应一位八进制、每 4 位对应一位十六进制,不够补前导零: