- 目的
- 基于经验,我们需要序列化的数据,通常小数(绝对值)多,大数少,所以出现了ZigZag编码,来减少编码数据的大小。
过程
双射
构建一个F(int) -> int,让绝对值小的数尽量小,绝对值大的数尽量大。
- 1n = (n << 1) ^ (n >> 31);
example
- 0 -> 0
- -1 -> 1
- 1 -> 2
- -2 -> 3
- 2 -> 4
变长编码
代码
- 1234567891011121314151617181920212223public static int encodeInt(int n, byte[] buf, int pos) {// move sign to low-order bit, and flip others if negativen = (n << 1) ^ (n >> 31);int start = pos;if ((n & ~0x7F) != 0) {buf[pos++] = (byte)((n | 0x80) & 0xFF);n >>>= 7;if (n > 0x7F) {buf[pos++] = (byte)((n | 0x80) & 0xFF);n >>>= 7;if (n > 0x7F) {buf[pos++] = (byte)((n | 0x80) & 0xFF);n >>>= 7;if (n > 0x7F) {buf[pos++] = (byte)((n | 0x80) & 0xFF);n >>>= 7;}}}}buf[pos++] = (byte) n;return pos - start;}
- 123456789等价于:whileif 第七位满1或有进位:n |= 0x80;取低位的8位作为一个byte写入buf;n >>>=7(无符号右移7位,在高位插0);else:取低位的8位作为一个byte写入bufend