封面故事:世界上第一块硬盘
计算机中的数据类型
今天我们可以在计算机里存下几乎任何数据:数字、文本、音频、图像、视频等。大多数现代计算机以二进制为基础,也就是说只能存储与处理 0 和 1。那么,计算机是如何存这些数据的?
答案是:所有数据最终都以二进制形式落盘;我们再定义一套「表示方法」把 0/1 映射为人类可理解的内容。
bit 是什么?
bit(比特)是计算机中最小的信息单位,表示一个 0 或 1。
bit pattern 是什么?
比特串(bit pattern/bit stream)是按顺序排列的一串比特。
针对不同用途,我们为同样的比特串定义不同含义并约定映射规则。理论上,只要长度足够长,比特串可以表示任何东西——甚至整个宇宙。
定点数存储
定点数通常用来表示整数,小数点固定在数值最右边。
|
|
为节省空间(让比特串更短),整数常见两种记法:无符号记法、带符号记法。
无符号记法(Unsigned)
取值范围为 [0, 2^n),n 为比特长度。
- 写入举例:把十进制 7 存到 8 位单元中
|
|
约定俗成地,8 位为一字节(byte)。
-
读取:把二进制按权展开即可,如 00000111 -> 7。
-
溢出:若数值超出 8 位可表达范围会截断高位,如把 21 存入 4 位:
|
|
适用:数量(>=0)、地址、以及表示其它数据类型的底层编码等。
原码(Signed absolute value)
很少使用,问题见下。范围为 (-2^(n-1), 2^(n-1))。最高位为符号位:0 正、1 负。
-
写入示例: | 十进制 | 符号 | 数据 | 结果 | | 7 | 0 | 0000111 | 00000111 | | -12 | 1 | 0001100 | 10001100 |
-
读取步骤:看符号位 -> 把其余位当无符号数展开。
-
问题:0 有 +0 和 -0 两种表示,造成歧义。
补码(Two’s complement)
为解决「双零」问题而生,现今整数存储的标准。范围为 [-2^(n-1), 2^(n-1))。
-
正数与原码相同;负数需转为补码。快速求补码方法:从最低位向左,遇到第一个 1 之前保持不变,左侧各位取反(仅对数据位,符号位保持 1)。
-
读取负数:对补码再做一次「求补」即可还原;对同一数做两次补码运算会回到原数。
-
仍会发生溢出,例如把 -130 存入 8 位会变成 126。
浮点数存储
浮点数通过「移动小数点」表示很大或很小的数。一个浮点数包含三部分:
- 符号(S):正负号
- 指数(E):小数点位置
- 尾数(F):有效数字
通常使用科学计数法:如 0.000000101 = 1.01 × 2^(-7)。
标准化:二进制非零数最高有效位恒为 1,可省略以节省存储,得到 .01 × 2^(-7)。
指数偏移:为避免存负指数,引入偏移量,把范围平移为非负。偏移量为 2^(k-1)-1,其中 k 为指数位数。
IEEE 754: Float32 与 Float64
- Float32:1 位符号 + 8 位指数 + 23 位尾数
- Float64:1 位符号 + 11 位指数 + 52 位尾数
二者的可表示范围不同,但都存在溢出;当 S=0、E=0、F=0 时表示 +0.0(-0.0 也存在于标准中)。
文本存储
文本由字符构成,关键在于字符编码规则。
- ASCII:7 位,最多 128 个字符,范围有限。
- Unicode:现代通用字符集,覆盖几乎所有语言与符号,常以 32 位编码为抽象模型;ASCII 是其子集。
音频存储
音频并非离散定义的对象,通常以「采样 + 量化 + 编码」近似模拟。
- 采样率:每秒采样次数,越高还原细节越多。常见约 40kHz。
- 量化:用数字表示每个采样值,常用整数近似。
- 位深(bits per sample):单个采样的位数,越高单点精度越高。
- 码率 = 采样率 × 位深;文件大小 = 码率 × 时长。
示例:1 分钟、采样率 40000、16 位深 -> 码率 640Kb/s,体积约 3.84MB。
图像存储
分为位图与矢量图。
位图(Bitmap)
由像素组成,需要说明像素数量(分辨率)与像素颜色(色深)。
- 分辨率:如 1920×1080、2560×1440、3840×2160。
- 色深:每像素使用的位数,常见 24 位 RGB,可表示 16777216 种颜色。
- 优点:能表达复杂内容、摄影普遍使用;缺点:放大后失真。
矢量图(Vector)
由绘制指令组成(如圆心、半径、描边/填充颜色)。
- 优点:任意缩放不失真、体积小;缺点:需专业软件生成,不适合表现复杂真实场景。
视频存储
视频由一系列图像按帧率快速播放而成。若逐帧无压存储,体积会极其庞大,因此实际视频文件均采用压缩编码。