目录
[差分序列做 BLE (RLE) 压缩原理](#差分序列做 BLE (RLE) 压缩原理)
[0. 先明确前提](#0. 先明确前提)
[1. 核心思想:BLE = RLE + 变长存储](#1. 核心思想:BLE = RLE + 变长存储)
[2. 为什么要分「小差值」和「大差值」?](#2. 为什么要分「小差值」和「大差值」?)
[3. 详细解析:小差值(-64 ~ +63)→ 1 字节存储](#3. 详细解析:小差值(-64 ~ +63)→ 1 字节存储)
[4. 详细解析:大差值 → 标记 0x80 + 2 字节](#4. 详细解析:大差值 → 标记 0x80 + 2 字节)
[5. 详细解析:计数 → 固定 1 字节](#5. 详细解析:计数 → 固定 1 字节)
[6. 最终 BLE (RLE) 存储格式](#6. 最终 BLE (RLE) 存储格式)
[7. 例子](#7. 例子)
差分序列做 BLE (RLE) 压缩原理
底层原理:
- 小差值(-64 ~ +63):用 1 字节存
- 大差值:用 标记 0x80 + 2 字节存
- 计数:固定 1 字节
0. 先明确前提
你现在已经做完 组间差分 得到了一串 90 个 int16 差值:
diff[0...89]
这些差值特点:
- 大部分 = 0
- 少量 = ±1、±2、±3
- 极少 = 超过 ±63
所以我们要做的就是:把这 90 个数字,用尽可能少的字节存起来
1. 核心思想:BLE = RLE + 变长存储
BLE = Basic Line Encoding
本质 = RLE(行程编码)+ 自适应短值压缩
RLE 原理一句话:连续相同的数字,不重复存,只存(值,重复次数)
例如:
0,0,0,0,0 → 存成 (0, 5)
2. 为什么要分「小差值」和「大差值」?
因为:
- 99% 的差值都很小(-64 ~ +63)
- 没必要每个都用 2 字节存
- 能塞进 1 个字节 就用 1 字节
- 塞不下才用 2 字节 + 标记位
这就是 变长存储,压缩比极高。
3. 详细解析:小差值(-64 ~ +63)→ 1 字节存储
范围:-64 ≤ diff ≤ +63
存储格式:
[1字节 有符号差值]
为什么是 -64 ~ +63?
因为:1 个字节(8bit)有符号数范围 = -128 ~ +127 但我们用 最高位作为标志位(后面讲)所以可用范围只剩:
-64 ~ +63(共 128 个值)
例子:
- 差值 = 0 → 存
0x00 - 差值 = 5 → 存
0x05 - 差值 = -1 → 存
0xFF - 差值 = -64 → 存
0xC0
全部 只用 1 字节!
4. 详细解析:大差值 → 标记 0x80 + 2 字节
范围:差值 <-64 或 差值> +63
存储格式:
[0x80 标记] + [2字节 完整int16差值]
规则:
- 只要看到第一个字节是 0x80
- 就知道:这是一个大差值
- 后面 2 字节 才是真实值
为什么用 0x80 做标记?
因为:
- 小差值范围:0x00 ~ 0x7F = 0 ~ 127
- 0x80 不在小差值范围内
- 不会冲突
- 解压时能精准识别
例子:
差值 = 100 → 存储:
0x80, 0x00, 0x64
差值 = -100 → 存储:
0x80, 0xFF, 0x9C
5. 详细解析:计数 → 固定 1 字节
计数 = 连续相同差值出现多少次
[1字节 计数]
范围:1 ~ 255
足够用了,因为你总共才 90 个参数。
6. 最终 BLE (RLE) 存储格式
情况 A:小差值
[1字节 差值] + [1字节 计数]
→ 总共 2 字节
情况 B:大差值
[0x80] + [2字节 差值] + [1字节 计数]
→ 总共 4 字节
7. 例子
假设差分序列是:
0,0,0,0, 1,1, -2,-2,-2, 5, 100
压缩过程:
0,0,0,0→ 小值 →0x00, 0x041,1→ 小值 →0x01, 0x02-2,-2,-2→ 小值 →0xFE, 0x035→ 小值 →0x05, 0x01100→ 大值 →0x80, 0x00, 0x64, 0x01
最终压缩数据:
00 04, 01 02, FE 03, 05 01, 80 00 64 01
效果:
原始:11×2 = 22 字节 压缩后:12 字节