指数哥伦布码
0赞一、正数0阶哥伦布编码
对于一个需要编码的数 x,按照以下的几步进行编码:
1. 按照二进制形式写下 x+1,
2. 根据写下的数字,计算出当前数值的位数,然后在该数的前面加上当前数值位数减一后得到的数值个数的零。
例如:编码“3”
1. 该数加一后(即4)的二进制为100,
2. 当前数值的位数是三位,3减去1后得到2,所以在“100”的前方加上两个零,得“00100”即为3的哥伦布码。
下面列出1-8的哥伦布码:
0 ⇒ 1 ⇒ 1
1 ⇒ 10 ⇒ 010
2 ⇒ 11 ⇒ 011
3 ⇒ 100 ⇒ 00100
4 ⇒ 101 ⇒ 00101
5 ⇒ 110 ⇒ 00110
6 ⇒ 111 ⇒ 00111
7 ⇒ 1000 ⇒ 0001000
8 ⇒ 1001 ⇒ 0001001
二、负数0阶哥伦布编码
每一个负数进行编码的时候,将其映射到其绝对值的两倍。即-4映射为8进行编码;正数的映射为其两倍减一进行编码,即4映射为7进行编码。
例如:
0 ⇒ 0 ⇒ 1 ⇒ 1
1 ⇒ 1 ⇒ 10 ⇒ 010
−1 ⇒ 2 ⇒ 11 ⇒ 011
2 ⇒ 3 ⇒ 100 ⇒ 00100
−2 ⇒ 4 ⇒ 101 ⇒ 00101
3 ⇒ 5 ⇒ 110 ⇒ 00110
−3 ⇒ 6 ⇒ 111 ⇒ 00111
4 ⇒ 7 ⇒ 1000 ⇒ 0001000
−4 ⇒ 8 ⇒ 1001 ⇒ 0001001
三、K阶指数哥伦布码
为了用更少的比特表示更大的数值,可以使用多阶指数哥伦布编码(代价是相比起之前的0阶哥伦布码来书,小的数值可能需要更多的比特去表示)
进行K阶哥伦布编码的步骤是
1. 确定进行编码的阶数K
2. 将原数映射到” X + (2^k) -1” (即如果在3阶条件下编码4,则其将被映射到4+2^3-1=11)
3. 将上一步骤得到的数值进行0阶编码得到0阶哥伦布码(11->0001100)
4. 去掉码的前部分k个前导零(0001100->1100) ;4的3阶哥伦布编码为1100;
四、解码
在进行解码的时候,从bit stream中寻找第一个非零比特值,然后把之前遇到的零的个数存在leadingzerobit参数中,即可根据该参数去被编码值了
解析k阶指数哥伦布码时,首先从比特流的当前位置开始寻找第一个非零比特,并将找到的零比特个数记为leadingZeroBits,然后根据leadingZeroBits计算CodeNum。用伪代码描述如下:
下表给出了0阶、1阶、2阶和3阶指数哥伦布码的结构。指数哥伦布码的比特串分为“前缀”和“后缀”两部分。前缀由leadingZeroBits 个连续的0和一个1构成,后缀由leadingZeroBits+k个比特构成,即表中的xi串,i的范围为0~(leadingZeroBits+k- 1),每个xi的值为0或1.
read_bit(n)
返回位流的随后n个二进制位,MSB在前,同时位流指针前移n个二进制位。如果n等于0,则返回0,位流指针不前移。
函数也用于解析过程和解码过程的描述。
实例:
例如对:56进行3阶哥伦布编码解码
1) 编码
56映射码值:56+2^3-1=63;(63+1=64;64二进制数100_0000)
一共7bit,所以需要补充6个0为0000_00100_0000;在去掉K(3)个零,为00_0100_0000;
2) 解码
leadingZeroBits = −1;
for( b = 0; !b; leadingZeroBits++ )
b = read_bits( 1 )
变量 codeNum 按照如下方式赋值:
codeNum = 2^(leadingZeroBits+k) – 2^K + read_bits( leadingZeroBits +K)这里 read_bits( leadingZeroBits+K )的返回值使用高位在先(从右到左)的二进制无符号整数表示。
000100_0000 分析得到 leadingzerobits=3 (!b 即b为1)
codeNum = 2的6次方-2^3+read_bits(6) (次数read_bits已经读到了0001这位 再读6位:000000为0)=64-8+0=56;
