ProtoBuffer----数据的zigzag编码

869 阅读3分钟

如果使用了sint32这些类型,当数据为负数时,会先使用zigzag进行编码,把数据变成无符号的,然后再通过varint进行编码。不多说自己举个栗子。

举个栗子

股票跌了收益为负的,假设为-2

					符号位  2原来的二进制位码
步骤一:0000 0000 0000 0000  0000 0000   1     000 0010
步骤二:1111 1111 1111 1111  1111 1111   1     111 1101  // 对2的原码取反
步骤三:1111 1111 1111 1111  1111 1111   1     111 1110  // 整个字节串+1   到此表示为-2(二进制)
步骤四:111 1111 1111 1111  1111 1111   1     111 11100  // n<<1 -->整体左移一位最后补0
步骤五:1111 1111 1111 1111  1111 1111   1     111 1111  // n>>31 --->整体右移31位最高位补31个1
步骤六:把步骤四和步骤五通过^异或位运算:
1111 1111 1111 1111  1111 1111 1111 1100
									   ^
1111 1111 1111 1111  1111 1111 1111 1111
----------------------------------------
0000 0000 0000 0000  0000 0000 0000 0011  // 异或位运算后结果为3

结论:-2经过zigzag编码后变成了3,把负数有符号的编码成无符号的,然后再进行varint编码来压缩数据。


0000 0000 0000 0000  0000 0000   1     000 1010
1111 1111 1111 1111  1111 1111   1     111 0101
1111 1111 1111 1111  1111 1111   1     111 0110
111 1111 1111 1111  1111 1111   1     111 01100  n<<1
1111 1111 1111 1111  1111 1111   1     111 1111  n>>31
^
1111 1111 1111 1111  1111 1111   1110 1100
1111 1111 1111 1111  1111 1111   1111 1111
0000 0000 0000 0000  0000 0000   0001 0011   
-10 变成 19: