Гамма-код Элиаса: различия между версиями

Материал из in.wiki
Перейти к навигации Перейти к поиску
w>Structor
(+ {{изолированная статья|сирота2}} с помощью AWB)
м (45 версий импортировано: Импорт из Википедии)
 
(не показана 41 промежуточная версия 25 участников)
Строка 1: Строка 1:
{{изолированная статья|сирота2}}
+
'''Гамма-код Элиаса''' — это [[универсальный код]] для кодирования положительных целых чисел, разработанный [[Элиас, Питер|Питером Элиасом]]. Он обычно используется при кодировании целых чисел, максимальное значение которых не может быть определено заранее.
{{тупиковая статья}}
 
'''Гамма-код Элиаса''' — это универсальный код для кодирования положительных целых чисел, разработанный Питером Элиасом. Он обычно используется при кодировании целых чисел, максимальное значение которых не может быть определено заранее.
 
  
 +
== Описание алгоритма ==
 
Чтобы закодировать число:
 
Чтобы закодировать число:
# Запиишите его в двоичной форме.
+
# Записать его в двоичной форме.
# Отнимите(вычтите) единицу из числа битов, записанных в шаге 1 и припишите спереди недостающие нули.
+
# Перед двоичным представлением числа дописать нули. Количество нулей на единицу меньше количества битов двоичного представления числа.
  
 
Аналогичный способ описания этого процесса:
 
Аналогичный способ описания этого процесса:
# Разделите целое число на самую большую степень 2, которую оно включает (2N), и на оставшиеся N двоичных цифр от данного целого числа.
+
# Выделить из целого числа старший значащий бит (самую большую степень 2, которую число включает — 2<sup>N</sup>) и младшие N бит.
# Запишите N в унарном коде; то есть N нолей следующих за единицей.
+
# Записать N в унарном коде; то есть N нолей, за которыми следует единица.
# Присоедините оставшиеся N двоичных цифр к этому представлению N.
+
# Дописать N младших двоичных цифр числа следом за этим унарным кодом.
  
 
Начало кодирования:
 
Начало кодирования:
<source lang="html4strict">
 
                              Предполагаемые вероятности
 
1 = 20 + 0 = 1                  1/2
 
2 = 21 + 0 = 010                1/8
 
3 = 21 + 1 = 011                "
 
4 = 22 + 0 = 00100              1/32
 
5 = 22 + 1 = 00101              "
 
6 = 22 + 2 = 00110              "
 
7 = 22 + 3 = 00111              "
 
8 = 23 + 0 = 0001000            1/128
 
9 = 23 + 1 = 0001001            "
 
10 = 23 + 2 = 0001010            "
 
11 = 23 + 3 = 0001011            "
 
12 = 23 + 4 = 0001100            "
 
13 = 23 + 5 = 0001101            "
 
14 = 23 + 6 = 0001110            "
 
15 = 23 + 7 = 0001111            "
 
16 = 24 + 0 = 000010000          1/512
 
17 = 24 + 1 = 000010001          "
 
 
</source>
 
 
Распределение предполагаемых вероятностей для кодов добавлено для понятности.
 
 
Чтобы декодировать закодированное Гамма кодом Элиаса число следует:
 
 
# Считать все встречающиеся до первой 1(единицы) нули. Назовем это количество нолей N.
 
# Принимая во внимание единицу, которая была достигнута как первая цифра целого числа, с значением 2N, считайте оставшиеся N цифр целого числа.
 
 
  
Гамма кодирование используется в приложениях, где самое большое значение не может быть известно заранее, или чтобы сжать данные, в которых маленькие значения встречаются наиболее часто чем большие.
+
{| class="standard" style="text-align:right"
 +
! Число || Значение || Кодирование || Предполагаемая<br />вероятность
 +
|-
 +
| 1 || 2<sup>0</sup> + 0 || 1 || 1/2
 +
|-
 +
| 2 || 2<sup>1</sup> + 0 || 0 1 0 || 1/8
 +
|-
 +
| 3 || 2<sup>1</sup> + 1 || 0 1 1 || 1/8
 +
|-
 +
| 4 || 2² + 0 || 00 1 00 || 1/32
 +
|-
 +
| 5 || 2² + 1 || 00 1 01 || 1/32
 +
|-
 +
| 6 || 2² + 2 || 00 1 10 || 1/32
 +
|-
 +
| 7 || 2² + 3 || 00 1 11 || 1/32
 +
|-
 +
| 8 || 2³ + 0 || 000 1 000 || 1/128
 +
|-
 +
| 9 || 2³ + 1 || 000 1 001 || 1/128
 +
|-
 +
|10 || 2³ + 2 || 000 1 010 || 1/128
 +
|-
 +
|11 || 2³ + 3 || 000 1 011 || 1/128
 +
|-
 +
|12 || 2³ + 4 || 000 1 100 || 1/128
 +
|-
 +
|13 || 2³ + 5 || 000 1 101 || 1/128
 +
|-
 +
|14 || 2³ + 6 || 000 1 110 || 1/128
 +
|-
 +
|15 || 2³ + 7 || 000 1 111 || 1/128
 +
|-
 +
|16 || 2<sup>4</sup> + 0 || 0000 1 0000 || 1/512
 +
|-
 +
|17 || 2<sup>4</sup> + 1 || 0000 1 0001 || 1/512
 +
|-
 +
|… || || ||
 +
|}
  
 +
Распределение предполагаемых вероятностей для кодов добавлено для ясности.
  
== Обобщения ==
+
Чтобы декодировать закодированное гамма-кодом Элиаса число следует:
  
 +
# Считать все нули, встречающиеся до первой 1. Пусть N — количество этих нулей.
 +
# Принимая во внимание единицу, которая станет первым (самая значащим) битом целого числа, со значением 2<sup>N</sup>, считать оставшиеся N цифр целого числа.
  
Гамма кодирование не подходит для кодирования нулевых значений или отрицательных чисел. Единственный способ закодировать ноль — прибавить к нему 1 до кодирования и отнять после декодирования. Другой способ — приписать в начале любой ненулевой код с 1 , а затем кодировать ноль как простой 0. Единственный способ закодировать все положительный числа — перед началом кодирования установить биекцию (соответствие), отображая целые числа из (0, 1, −1, 2, −2, 3, −3, …) в (1, 2, 3, 4, 5, 6, 7, …).
+
Гамма-кодирование используется в приложениях, где самое большое значение не может быть известно заранее, или чтобы сжать данные, в которых маленькие значения встречаются более часто чем большие.
  
 +
== Обобщение ==
 +
<!-- на этот заголовок есть ссылки из других статей -->
 +
Гамма-кодирование не подходит для кодирования нулевых значений или отрицательных чисел. Один из способов закодировать ноль — прибавить ко всем числам 1 до кодирования и отнять после декодирования. Другой способ — приписать в начале любого ненулевого кода 1 , а затем кодировать ноль как простой 0. Единственный способ закодировать все целые числа — перед началом кодирования установить [[биекция|биекцию]] (соответствие), отображая целые числа из (0, 1, −1, 2, −2, 3, −3, …) в (1, 2, 3, 4, 5, 6, 7, …).
  
 
== Пример программного кода ==
 
== Пример программного кода ==
 
<source lang="c">
 
<source lang="c">
Кодирование
+
// Кодирование
 
void eliasGammaEncode(char* source, char* dest)
 
void eliasGammaEncode(char* source, char* dest)
 
{
 
{
 
     IntReader intreader(source);
 
     IntReader intreader(source);
 
     BitWriter bitwriter(dest);
 
     BitWriter bitwriter(dest);
     while(intreader.hasLeft())    
+
     while(intreader.hasLeft())
 
     {
 
     {
 
       int num = intreader.getInt();
 
       int num = intreader.getInt();
Строка 65: Строка 79:
 
       for (int a=0; a < l; a++)
 
       for (int a=0; a < l; a++)
 
       {       
 
       {       
           bitwriter.putBit(false); //поместите ноли, чтобы показать сколько бит будут следовать
+
           bitwriter.putBit(false); //поместить нули, чтобы показать, сколько бит будут следовать
 
       }
 
       }
       bitwriter.putBit(true);//пометьте конец нолей
+
       bitwriter.putBit(true); //пометить конец нолей
       for (int a=0; a < l; a++) //напишите биты как простые двоичные числа
+
       for (int a = l-1; a >= 0; a--) //записать биты как простые двоичные числа
 
       {
 
       {
                  if (num & 1 << a)
+
          if (num & (1 << a))
                    bitwriter.putBit(true);
+
            bitwriter.putBit(true);
                  else
+
          else
                    bitwriter.putBit(false);
+
            bitwriter.putBit(false);
 
       }
 
       }
 
     }
 
     }
Строка 79: Строка 93:
 
     bitwriter.close();
 
     bitwriter.close();
 
}
 
}
Декодирование
+
// Декодирование
 
void eliasGammaDecode(char* source, char* dest)
 
void eliasGammaDecode(char* source, char* dest)
 
{
 
{
Строка 87: Строка 101:
 
     while(bitreader.hasLeft())
 
     while(bitreader.hasLeft())
 
     {
 
     {
         while(!bitreader.getBit() || bitreader.hasLeft())numberBits++; //продолжаем вычитку пока не достигнем единицы...
+
         while(!bitreader.getBit() || bitreader.hasLeft())numberBits++; //продолжить чтение пока не встретится единица...
 
         int current = 0;
 
         int current = 0;
         for (int a=0; a < numberBits; a++) //считывание битов numberBits
+
         for (int a=0; a < numberBits; a++) //прочитать numberBits битов
 
         {
 
         {
 
             if (bitreader.getBit())
 
             if (bitreader.getBit())
 
               current += 1 << a;
 
               current += 1 << a;
 
         }
 
         }
         //запишите его как 32х битное число
+
         //записать его как 32-битное число
 
   
 
   
         current= current | ( 1 << numberBits ) ;//последний бит не декодируется!
+
         current = current | ( 1 << numberBits ) ;//последний бит не декодируется!
         for (int a=0; a < 32; a++) //Read numberBits bits
+
         for (int a=0; a < 32; a++) //прочитать numberBits битов
 
         {
 
         {
 
             if (current & (1 << a))
 
             if (current & (1 << a))
Строка 108: Строка 122:
 
</source>
 
</source>
  
 +
== См. также ==
 +
* [[Омега-код Элиаса]]
 +
* [[Дельта-код Элиаса]]
 +
== Литература ==
 +
* {{статья |author-first=Peter |author-last=Elias |заглавие=Universal codeword sets and representations of the integers |издание={{Нп3|IEEE Transactions on Information Theory}} |том=21 |номер=2 |страницы=194—203 |ссылка=http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=1055349 |doi=10.1109/tit.1975.1055349 |язык=en |тип=journal |месяц=3 |год=1975}}
  
 +
{{Методы сжатия}}
  
== Ссылки ==
+
[[Категория:Алгоритмы сжатия без потерь]]
Оригинал статьи на английском
 
{{cite web
 
| url = http://en.wikipedia.org/wiki/Elias_gamma_coding
 
| title = Elias gamma coding
 
}}
 

Текущая версия от 00:51, 20 августа 2025

Гамма-код Элиаса — это универсальный код для кодирования положительных целых чисел, разработанный Питером Элиасом. Он обычно используется при кодировании целых чисел, максимальное значение которых не может быть определено заранее.

Описание алгоритма[править | править код]

Чтобы закодировать число:

  1. Записать его в двоичной форме.
  2. Перед двоичным представлением числа дописать нули. Количество нулей на единицу меньше количества битов двоичного представления числа.

Аналогичный способ описания этого процесса:

  1. Выделить из целого числа старший значащий бит (самую большую степень 2, которую число включает — 2N) и младшие N бит.
  2. Записать N в унарном коде; то есть N нолей, за которыми следует единица.
  3. Дописать N младших двоичных цифр числа следом за этим унарным кодом.

Начало кодирования:

Число Значение Кодирование Предполагаемая
вероятность
1 20 + 0 1 1/2
2 21 + 0 0 1 0 1/8
3 21 + 1 0 1 1 1/8
4 2² + 0 00 1 00 1/32
5 2² + 1 00 1 01 1/32
6 2² + 2 00 1 10 1/32
7 2² + 3 00 1 11 1/32
8 2³ + 0 000 1 000 1/128
9 2³ + 1 000 1 001 1/128
10 2³ + 2 000 1 010 1/128
11 2³ + 3 000 1 011 1/128
12 2³ + 4 000 1 100 1/128
13 2³ + 5 000 1 101 1/128
14 2³ + 6 000 1 110 1/128
15 2³ + 7 000 1 111 1/128
16 24 + 0 0000 1 0000 1/512
17 24 + 1 0000 1 0001 1/512

Распределение предполагаемых вероятностей для кодов добавлено для ясности.

Чтобы декодировать закодированное гамма-кодом Элиаса число следует:

  1. Считать все нули, встречающиеся до первой 1. Пусть N — количество этих нулей.
  2. Принимая во внимание единицу, которая станет первым (самая значащим) битом целого числа, со значением 2N, считать оставшиеся N цифр целого числа.

Гамма-кодирование используется в приложениях, где самое большое значение не может быть известно заранее, или чтобы сжать данные, в которых маленькие значения встречаются более часто чем большие.

Обобщение[править | править код]

Гамма-кодирование не подходит для кодирования нулевых значений или отрицательных чисел. Один из способов закодировать ноль — прибавить ко всем числам 1 до кодирования и отнять после декодирования. Другой способ — приписать в начале любого ненулевого кода 1 , а затем кодировать ноль как простой 0. Единственный способ закодировать все целые числа — перед началом кодирования установить биекцию (соответствие), отображая целые числа из (0, 1, −1, 2, −2, 3, −3, …) в (1, 2, 3, 4, 5, 6, 7, …).

Пример программного кода[править | править код]

// Кодирование
void eliasGammaEncode(char* source, char* dest)
{
     IntReader intreader(source);
     BitWriter bitwriter(dest);
     while(intreader.hasLeft())
     {
      int num = intreader.getInt();
      int l = log2(num);
      for (int a=0; a < l; a++)
      {       
          bitwriter.putBit(false); //поместить нули, чтобы показать, сколько бит будут следовать
      }
      bitwriter.putBit(true); //пометить конец нолей
      for (int a = l-1; a >= 0; a--) //записать биты как простые двоичные числа
      {
          if (num & (1 << a))
             bitwriter.putBit(true);
          else
             bitwriter.putBit(false);
      }
     }
     intreader.close();
     bitwriter.close();
}
// Декодирование
void eliasGammaDecode(char* source, char* dest)
{
     BitReader bitreader(source);
     BitWriter bitwriter(dest);
     int numberBits = 0;
     while(bitreader.hasLeft())
     {
        while(!bitreader.getBit() || bitreader.hasLeft())numberBits++; //продолжить чтение пока не встретится единица...
        int current = 0;
        for (int a=0; a < numberBits; a++) //прочитать numberBits битов
        {
            if (bitreader.getBit())
               current += 1 << a;
        }
        //записать его как 32-битное число
 
        current = current | ( 1 << numberBits ) ;//последний бит не декодируется!
        for (int a=0; a < 32; a++) //прочитать numberBits битов
        {
            if (current & (1 << a))
               bitwriter.putBit(true);
            else
               bitwriter.putBit(false);
        }
     }
}

См. также[править | править код]

Литература[править | править код]

Ошибка Lua в Модуль:Navbox на строке 353: attempt to index local 'listText' (a nil value).