zigzag 是一个简单好用的小整数压缩算法。

原理

现在一般的计算机都是 32 位或者 64 位机了,每个数据的表示长度和范围都比较多。一个常见的数据类型 int 一般占 4 个字节,但是在实际使用时,数字并不会很大,经常不会超过几万(当然要看实际情况),比如下面几个例子

PLAINTEXT
number: 23
bit:    0000 0000 0000 0000 0000 0000 0001 0111
number: -33
bit:    1111 1111 1111 1111 1111 1111 1101 1111
点击展开查看更多

通过观察可以发现,小正数的左侧有大量的 0,小负数的左侧有大量的 1。zigzag 做的就是将左边的冗余数据全部换为 0,便于后续压缩

正数

拿 23 举例

  1. 将数字左移一位:0000 0000 0000 0000 0000 0000 0010 1110
  2. 符号位加到最后一位(正数符号位为 0 不用操作)

得到了最后的压缩结果:0000 0000 0000 0000 0000 0000 0010 1110

负数

拿 -33 举例

  1. 左移一位:1111 1111 1111 1111 1111 1111 1011 1110
  2. 符号位加到最后一位:1111 1111 1111 1111 1111 1111 1011 1111
  3. 除最后一位全部取反:0000 0000 0000 0000 0000 0000 0100 0001

得到了最后的压缩结果:0000 0000 0000 0000 0000 0000 0100 0001

解码

Zigzag1(n)Zigzag^{-1}(n) = (n << 1) ^ -(n & 1)

实现

CPP
uint32_t EncodeInt(int32_t number) {
  return number < 0 ? (((uint32_t)(-number)) * 2 - 1) : number * 2;
}

int32_t DecodeInt(uint32_t number) {
  return (number >> 1) ^ -(number & 1);
}
点击展开查看更多

下图是测试数字 -23 的结果:

fig

版权声明

作者: MiaoHN

链接: https://404notfixed.cn/posts/zigzag/

许可证: CC BY-NC-SA 4.0

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Please attribute the source, use non-commercially, and maintain the same license.

开始搜索

输入关键词搜索文章内容

↑↓
ESC
⌘K 快捷键