Дельта-код Элиаса или дельта-код Элиаса — универсальный код , кодирующий положительные целые числа, разработанный Питером Элиасом . [1] : 200
Чтобы закодировать число X ≥ 1:
Эквивалентный способ выражения того же процесса:
Для представления числа дельта Элиаса (δ) использует биты. [1] : 200 Это полезно для очень больших целых чисел, когда общее количество бит закодированного представления оказывается меньше [чем то, что можно было бы получить с помощью гамма-кодирования Элиаса ] из-за части предыдущего выражения.
Код начинается с использования вместо :
Число | Н | Н+1 | δ-кодирование | Подразумеваемая вероятность |
---|---|---|---|---|
1 = 2 0 | 0 | 1 | 1 | 1/2 |
2 = 2 1 + 0 | 1 | 2 | 0 1 0 0 | 1/16 |
3 = 2 1 + 1 | 1 | 2 | 0 1 0 1 | 1/16 |
4 = 2 2 + 0 | 2 | 3 | 0 1 1 00 | 1/32 |
5 = 2 2 + 1 | 2 | 3 | 0 1 1 01 | 1/32 |
6 = 2 2 + 2 | 2 | 3 | 0 1 1 10 | 1/32 |
7 = 2 2 + 3 | 2 | 3 | 0 1 1 11 | 1/32 |
8 = 2 3 + 0 | 3 | 4 | 00 1 00 000 | 1/256 |
9 = 2 3 + 1 | 3 | 4 | 00 1 00 001 | 1/256 |
10 = 2 3 + 2 | 3 | 4 | 00 1 00 010 | 1/256 |
11 = 2 3 + 3 | 3 | 4 | 00 1 00 011 | 1/256 |
12 = 2 3 + 4 | 3 | 4 | 00 1 00 100 | 1/256 |
13 = 2 3 + 5 | 3 | 4 | 00 1 00 101 | 1/256 |
14 = 2 3 + 6 | 3 | 4 | 00 1 00 110 | 1/256 |
15 = 2 3 + 7 | 3 | 4 | 00 1 00 111 | 1/256 |
16 = 2 4 + 0 | 4 | 5 | 00 1 01 0000 | 1/512 |
17 = 2 4 + 1 | 4 | 5 | 00 1 01 0001 | 1/512 |
Чтобы декодировать целое число, закодированное с помощью дельта-кода Элиаса:
Пример:
0010100111. 2 ведущих нуля в 0012. прочитать еще 2 бита, например 001013. декодировать N+1 = 00101 = 54. получить N = 5 − 1 = 4 оставшихся бита для полного кода, т.е. '0011'5. закодированное число = 2 4 + 3 = 19
Этот код можно обобщить до нуля или отрицательных целых чисел теми же способами, которые описаны в гамма-кодировании Элиаса .
void eliasDeltaEncode ( char * source , char * dest ) { IntReader intreader ( source ); BitWriter битрайтер ( dest ); в то время как ( intreader . hasLeft ()) { int num = intreader . получитьИнт (); интервал Лен = 0 ; int lengthOfLen = 0 ; len = 1 + floor ( log2 ( num )); // вычислить 1+floor(log2(num)) lengthOfLen = floor ( log2 ( len )); // вычислить floor(log2(len)) for ( int i = lengthOfLen ; i > 0 ; -- i ) bitwriter . outputBit ( 0 ); for ( int i = lengthOfLen ; i >= 0 ; -- i ) bitwriter . outputBit (( len >> i ) & 1 ); for ( int i = len -2 ; i >= 0 ; i -- ) bitwriter . outputBit (( num >> i ) & 1 ); } bitwriter . close (); intreader . close (); }
void eliasDeltaDecode ( char * source , char * dest ) { BitReader bitreader ( source ) ; IntWriter intwriter ( dest ); while ( bitreader.hasLeft ( )) { int num = 1 ; int len = 1 ; int lengthOfLen = 0 ; while ( ! bitreader.inputBit ()) // потенциально опасно с некорректными файлами.lengthOfLen ++ ; for ( int i = 0 ; i < lengthOfLen ; i ++ ) { len <<= 1 ; if ( bitreader.inputBit ( )) len | = 1 ; } for ( int i = 0 ; i < len -1 ; i ++ ) { num << = 1 ; if ( bitreader.inputBit ( ) ) num | = 1 ; } intwriter . putInt ( num ); // записываем значение } bitreader.close () ; intwriter.close ( ) ; }
Дельта-кодирование Элиаса не кодирует ноль или отрицательные целые числа. Один из способов кодирования всех неотрицательных целых чисел — добавить 1 перед кодированием и вычесть 1 после декодирования. Один из способов кодирования всех целых чисел — настроить биекцию , сопоставив все целые числа (0, 1, −1, 2, −2, 3, −3, ...) со строго положительными целыми числами (1, 2, 3, 4, 5, 6, 7, ...) перед кодированием. Эту биекцию можно выполнить с помощью кодирования «ZigZag» из Protocol Buffers (не путать с кодом Zigzag или кодированием энтропии JPEG Zig-zag ).