数制、补码、浮点数与字符¶
进位制:位置决定权重¶
\(b\) 进制的 \(n\) 位数可写为:
二进制适合两种稳定电平,十六进制则把每 4 位二进制压成一个符号,便于人阅读。比如:
转换时不要把十六进制当成另一种数据,只是同一位串的紧凑写法。
无符号数与模运算¶
\(n\) 位无符号数范围为 \(0\) 到 \(2^n-1\)。硬件加法器自然丢弃第 \(n+1\) 位进位,因此运算等价于模 \(2^n\):
8 位无符号数中,\(250+10\) 得到 \(4\)。这不是加法器算错,而是结果超出编码范围。
补码为何统一加减法¶
\(n\) 位补码把负数 \(-x\) 编码为 \(2^n-x\)。因此减法可变成加法:
例如 8 位中 \(-5\) 的编码为:
计算 \(7+(-5)\):
补码范围不对称:
所以最小负数没有对应的正数。两个同号数相加却得到异号结果,说明有符号溢出;无符号溢出则看最高位进位,两种判断不能混用。
定点数与浮点数¶
定点数约定小数点位置固定,硬件简单、误差可预测,常用于金额和嵌入式控制。浮点数用科学计数法换取更大动态范围。
IEEE 754 单精度由 1 位符号、8 位阶码和 23 位尾数组成。正规数的值为:
隐藏的前导 \(1\) 提高了一位有效精度。全零阶码用于零和非正规数,全一阶码用于无穷与 NaN。
为什么 0.1 + 0.2 不一定等于 0.3¶
\(0.1\) 在二进制中是无限循环小数,只能舍入到有限尾数。每次运算还要对阶、计算和再次舍入。因此浮点数近似实数,却不满足实数运算的全部代数律,例如:
在浮点计算中完全可能成立。扩大位数会减小误差,但不能消灭有限表示的根本限制。
字符:从字符集到字节编码¶
字符集回答“每个字符对应哪个码点”,编码回答“码点怎样变成字节”。ASCII 用 7 位覆盖基础英文字符。Unicode 为跨语言字符分配统一码点,UTF-8 再用 1 到 4 个字节变长编码这些码点。
UTF-8 与 ASCII 的前 128 个字符兼容,并让常见英文文本紧凑;代价是“字符数”不等于“字节数”,字符串随机定位更复杂。字形、字符、码点和字节是四个不同层次,乱码通常来自编码契约不一致。
选择表示的权衡¶
| 表示 | 优点 | 代价与限制 |
|---|---|---|
| 无符号整数 | 范围全部用于非负数 | 不能直接表达负数 |
| 补码整数 | 加减硬件统一 | 范围有限且不对称 |
| 定点数 | 可预测、实现简单 | 动态范围有限 |
| 浮点数 | 动态范围大 | 舍入、特殊值、运算非结合 |
| UTF-8 | 兼容 ASCII、跨语言 | 变长,字符处理更复杂 |
自测¶
- 写出 8 位补码中 \(-128\) 与 \(127\) 的编码,解释为何没有 \(+128\)。
- 何时应优先用定点数而不是浮点数?
- Unicode 码点和 UTF-8 字节序列有什么区别?