Jump to content

Вес Хэмминга

(Перенаправлено с Popcount )

Вес Хэмминга строки это количество символов, отличных от нулевого символа используемого алфавита . Таким образом, оно эквивалентно расстоянию Хэмминга от нулевой строки той же длины. Для наиболее типичного случая, строки битов , это количество единиц в строке или сумма цифр двоичного представления данного числа и нормы ℓ битового вектора. В этом двоичном случае его также называют подсчетом населения , [1] popcount , боковая сумма , [2] или суммирование битов . [3]

Примеры
Нить Вес Хэмминга
111 0 1 4
111 0 1 000 4
00000000 0
678 0 1234 0 567 10
График веса Хэмминга для чисел от 0 до 256. [4]

История и использование

[ редактировать ]

Гиря Хэмминга названа в честь Ричарда Хэмминга, хотя это понятие принадлежит не ему. [5] Вес Хэмминга двоичных чисел уже использовался в 1899 году Джеймсом Глейшером для получения формулы для количества нечетных биномиальных коэффициентов в одной строке треугольника Паскаля . [6] Ирвинг С. Рид ввел концепцию, эквивалентную весу Хэмминга в двоичном случае, в 1954 году. [7]

Вес Хэмминга используется в нескольких дисциплинах, включая теорию информации , теорию кодирования и криптографию . Примеры применения веса Хэмминга включают:

Эффективная реализация

[ редактировать ]

Подсчет численности битовой строки часто необходим в криптографии и других приложениях. Расстояние Хэмминга двух слов A и B можно рассчитать как вес Хэмминга A xor B . [1]

Проблема его эффективной реализации широко изучена. одна операция вычисления или параллельные операции над битовыми векторами На некоторых процессорах доступны . Для процессоров, лишенных этих функций, лучшие известные решения основаны на добавлении счетчиков в древовидную структуру. Например, чтобы подсчитать количество 1 бит в 16-битном двоичном числе a = 0110 1100 1011 1010, можно выполнить следующие операции:

Выражение Двоичный Десятичный Комментарий
a 01 10 11 00 10 11 10 10 27834 Исходный номер
b0 = (a >> 0) & 01 01 01 01 01 01 01 01 01 00 01 00 00 01 00 00 1, 0, 1, 0, 0, 1, 0, 0 Каждый второй бит из
b1 = (a >> 1) & 01 01 01 01 01 01 01 01 00 01 01 00 01 01 01 01 0, 1, 1, 0, 1, 1, 1, 1 Остальные биты из
c = b0 + b1 01 01 10 00 01 10 01 01 1, 1, 2, 0, 1, 2, 1, 1 Количество единиц в каждом 2-битном фрагменте
d0 = (c >> 0) & 0011 0011 0011 0011 0001 0000 0010 0001 1, 0, 2, 1 Каждый второй счет от c
d2 = (c >> 2) & 0011 0011 0011 0011 0001 0010 0001 0001 1, 2, 1, 1 Остальные отсчеты от c
e = d0 + d2 0010 0010 0011 0010 2, 2, 3, 2 Количество единиц в каждом 4-битном фрагменте
f0 = (e >> 0) & 00001111 00001111 00000010 00000010 2, 2 Каждый второй счет от e
f4 = (e >> 4) & 00001111 00001111 00000010 00000011 2, 3 Остальные отсчеты от e
g = f0 + f4 00000100 00000101 4, 5 Количество единиц в каждом 8-битном фрагменте
h0 = (g >> 0) & 0000000011111111 0000000000000101 5 Все остальные отсчеты от g
h8 = (g >> 8) & 0000000011111111 0000000000000100 4 Остальные отсчеты от g
i = h0 + h8 0000000000001001 9 Подсчет единиц во всем 16-битном слове

Здесь операции такие же, как в языке программирования C , поэтому X >> Y означает сдвиг X вправо на Y бит, X & Y означает побитовое И X и Y, а + — обычное сложение. Лучшие алгоритмы, известные для решения этой проблемы, основаны на концепции, проиллюстрированной выше, и приведены здесь: [1]

//types and constants used in the functions below
//uint64_t is an unsigned 64-bit integer variable type (defined in C99 version of C language)
const uint64_t m1  = 0x5555555555555555; //binary: 0101...
const uint64_t m2  = 0x3333333333333333; //binary: 00110011..
const uint64_t m4  = 0x0f0f0f0f0f0f0f0f; //binary:  4 zeros,  4 ones ...
const uint64_t m8  = 0x00ff00ff00ff00ff; //binary:  8 zeros,  8 ones ...
const uint64_t m16 = 0x0000ffff0000ffff; //binary: 16 zeros, 16 ones ...
const uint64_t m32 = 0x00000000ffffffff; //binary: 32 zeros, 32 ones
const uint64_t h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...

//This is a naive implementation, shown for comparison,
//and to help in understanding the better functions.
//This algorithm uses 24 arithmetic operations (shift, add, and).
int popcount64a(uint64_t x)
{
    x = (x & m1 ) + ((x >>  1) & m1 ); //put count of each  2 bits into those  2 bits 
    x = (x & m2 ) + ((x >>  2) & m2 ); //put count of each  4 bits into those  4 bits 
    x = (x & m4 ) + ((x >>  4) & m4 ); //put count of each  8 bits into those  8 bits 
    x = (x & m8 ) + ((x >>  8) & m8 ); //put count of each 16 bits into those 16 bits 
    x = (x & m16) + ((x >> 16) & m16); //put count of each 32 bits into those 32 bits 
    x = (x & m32) + ((x >> 32) & m32); //put count of each 64 bits into those 64 bits 
    return x;
}

//This uses fewer arithmetic operations than any other known  
//implementation on machines with slow multiplication.
//This algorithm uses 17 arithmetic operations.
int popcount64b(uint64_t x)
{
    x -= (x >> 1) & m1;             //put count of each 2 bits into those 2 bits
    x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits 
    x = (x + (x >> 4)) & m4;        //put count of each 8 bits into those 8 bits 
    x += x >>  8;  //put count of each 16 bits into their lowest 8 bits
    x += x >> 16;  //put count of each 32 bits into their lowest 8 bits
    x += x >> 32;  //put count of each 64 bits into their lowest 8 bits
    return x & 0x7f;
}

//This uses fewer arithmetic operations than any other known  
//implementation on machines with fast multiplication.
//This algorithm uses 12 arithmetic operations, one of which is a multiply.
int popcount64c(uint64_t x)
{
    x -= (x >> 1) & m1;             //put count of each 2 bits into those 2 bits
    x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits 
    x = (x + (x >> 4)) & m4;        //put count of each 8 bits into those 8 bits 
    return (x * h01) >> 56;  //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ... 
}

Вышеупомянутые реализации имеют лучшее поведение в наихудшем случае из всех известных алгоритмов. Однако, когда ожидается, что значение будет иметь несколько ненулевых битов, вместо этого может быть более эффективно использовать алгоритмы, которые считают эти биты по одному. Как описал Вегнер в 1960 году, [12] побитовое И для x с x - 1 отличается от x только обнулением младшего значащего ненулевого бита: вычитание 1 изменяет самую правую строку из 0 на 1 и меняет крайнюю правую 1 на 0. Если x изначально имел n бит, которые были 1, то всего лишь после n итераций этой операции x уменьшится до нуля. Следующая реализация основана на этом принципе.

//This is better when most bits in x are 0
//This algorithm works the same for all data sizes.
//This algorithm uses 3 arithmetic operations and 1 comparison/branch per "1" bit in x.
int popcount64d(uint64_t x)
{
    int count;
    for (count=0; x; count++)
        x &= x - 1;
    return count;
}

Если разрешено большее использование памяти, мы можем вычислить вес Хэмминга быстрее, чем описанные выше методы. Имея неограниченную память, мы могли бы просто создать большую таблицу поиска веса Хэмминга для каждого 64-битного целого числа. Если мы можем сохранить таблицу поиска функции Хэмминга для каждого 16-битного целого числа, мы можем сделать следующее, чтобы вычислить вес Хэмминга каждого 32-битного целого числа.

static uint8_t wordbits[65536] = { /* bitcounts of integers 0 through 65535, inclusive */ };
//This algorithm uses 3 arithmetic operations and 2 memory reads.
int popcount32e(uint32_t x)
{
    return wordbits[x & 0xFFFF] + wordbits[x >> 16];
}
//Optionally, the wordbits[] table could be filled using this function
int popcount32e_init(void)
{
    uint32_t i;
    uint16_t x;
    int count;
    for (i=0; i <= 0xFFFF; i++)
    {
        x = i;
        for (count=0; x; count++) // borrowed from popcount64d() above
            x &= x - 1;
        wordbits[i] = count;
    }
}

Мула и др. [13] показали, что векторизованная версия popcount64b может работать быстрее, чем специальные инструкции (например, popcnt на процессорах x64).

Минимальный вес

[ редактировать ]

В кодировании с исправлением ошибок минимальный вес Хэмминга, обычно называемый минимальным весом w min кода, представляет собой вес ненулевого кодового слова с наименьшим весом. Вес w кодового слова — это количество единиц в слове. Например, слово 11001010 имеет вес 4.

В линейном блочном коде минимальный вес также является минимальным расстоянием Хэмминга ( d min ) и определяет способность кода исправлять ошибки. Если w min = n , то d min = n и код исправит до d min /2 ошибок. [14]

Языковая поддержка

[ редактировать ]

Некоторые компиляторы C предоставляют встроенные функции, обеспечивающие подсчет битов. Например, GCC (начиная с версии 3.4 в апреле 2004 г.) включает встроенную функцию __builtin_popcount который будет использовать инструкцию процессора, если она доступна, или эффективную реализацию библиотеки в противном случае. [15] LLVM-GCC включает эту функцию начиная с версии 1.5 в июне 2005 года. [16]

В стандартной библиотеке C++ структура данных битового массива bitset имеет count() метод, который подсчитывает количество установленных битов. В C++20 новый заголовок <bit> был добавлен, содержащий функции std::popcount и std::has_single_bit, принимая аргументы целочисленных типов без знака.

В Java — расширяемая структура данных битового массива. BitSet имеет BitSet.cardinality() метод, который подсчитывает количество установленных битов. Кроме того, существуют Integer.bitCount(int) и Long.bitCount(long) функции для подсчета битов в примитивных 32-битных и 64-битных целых числах соответственно. Кроме того, BigInteger Целочисленный класс произвольной точности также имеет BigInteger.bitCount() метод, который считает биты.

В Python int тип имеет bit_count() метод для подсчета количества установленных бит. Эта функциональность была представлена ​​в Python 3.10, выпущенном в октябре 2021 года. [17]

В Common Lisp функция logcount, учитывая неотрицательное целое число, возвращает количество 1 бит. (Для отрицательных целых чисел возвращается количество нулевых битов в записи дополнения до 2.) В любом случае целое число может быть БОЛЬШИМ ЧИСЛОМ.

Начиная с GHC 7.4, базовый пакет Haskell имеет popCount функция доступна для всех типов, которые являются экземплярами Bits класс (доступен на Data.Bits модуль). [18]

MySQL- версия языка SQL обеспечивает BIT_COUNT() как стандартная функция. [19]

Фортран 2008 имеет стандартную, внутреннюю, элементарную функцию. popcnt возврат количества ненулевых битов в целом числе (или целочисленном массиве). [20]

Некоторые программируемые карманные научные калькуляторы имеют специальные команды для расчета количества установленных бит, например #B на НР-16С [3] [21] и WP 43S , [22] [23] #BITS[24] [25] или BITSUM[26] [27] на эмуляторах HP-16C и nBITS на WP 34S . [28] [29]

FreePascal реализует popcnt начиная с версии 3.0. [30]

Поддержка процессора

[ редактировать ]

См. также

[ редактировать ]
  1. ^ Jump up to: а б с д и ж г Уоррен-младший, Генри С. (2013) [2002]. Хакерское наслаждение (2-е изд.). Аддисон Уэсли - Pearson Education, Inc., стр. 81–96. ISBN  978-0-321-84268-8 . 0-321-84268-5.
  2. ^ Кнут, Дональд Эрвин (2009). «Побитовые приемы и методы; Двоичные диаграммы решений». Искусство компьютерного программирования . Том. 4, выпуск 1. Addison-Wesley Professional . ISBN  978-0-321-58050-4 . (Примечание. Черновик главы 1b, заархивированный 12 марта 2016 г. на Wayback Machine , доступен для скачивания.)
  3. ^ Jump up to: а б Руководство пользователя Hewlett-Packard HP-16C для компьютерных специалистов (PDF) . Компания Хьюлетт-Паккард . Апрель 1982 г. 00016-90001. Архивировано (PDF) из оригинала 28 марта 2017 г. Проверено 28 марта 2017 г.
  4. ^ Р.Угальде, Лоуренс. «Подсчет населения языка программирования Fōrmulæ» . Формулы . Проверено 2 июня 2024 г.
  5. ^ Томпсон, Томас М. (1983). От кодов, исправляющих ошибки, через сферические упаковки к простым группам . Математические монографии Каруса № 21. Математическая ассоциация Америки . п. 33.
  6. ^ Глейшер, Джеймс Уитбред Ли (1899). «О вычете коэффициента биномиальной теоремы по простому модулю» . Ежеквартальный журнал чистой и прикладной математики . 30 : 150–156. (Примечание. См., в частности, последний абзац стр. 156.)
  7. ^ Рид, Ирвинг Стой (1954). «Класс кодов, исправляющих множественные ошибки, и схема декодирования». Профессиональная группа IRE по теории информации . ПГИТ-4. Институт радиоинженеров (ИРЭ): 38–49.
  8. ^ Коэн, Жерар Д .; Лобштейн, Антуан; Наккеш, Дэвид; Земор, Жиль (1998). «Как улучшить черный ящик возведения в степень». В Нюберге, Кайса (ред.). Достижения в криптологии – EUROCRYPT '98, Международная конференция по теории и применению криптографических методов, Эспоо, Финляндия, 31 мая – 4 июня 1998 г., Текущие материалы . Конспекты лекций по информатике. Том. 1403. Спрингер. стр. 211–220. дои : 10.1007/BFb0054128 . ISBN  978-3-540-64518-4 .
  9. ^ Стойка, И.; Моррис, Р.; Либен-Ноуэлл, Д.; Каргер, доктор медицинских наук; Каашук, МФ; Дабек, Ф.; Балакришнан, Х. (февраль 2003 г.). «Chord: масштабируемый протокол однорангового поиска для интернет-приложений». Транзакции IEEE/ACM в сети . 11 (1): 17–32. дои : 10.1109/TNET.2002.808407 . S2CID   221276912 . Раздел 6.3: «В общем, количество пальцев, за которыми нам нужно следовать, будет равно числу единиц в двоичном представлении расстояния от узла до запроса».
  10. ^ Jump up to: а б SPARC International, Inc. (1992). «A.41: Подсчет населения. Примечание по программированию» . Руководство по архитектуре SPARC: версия 8 (изд. версии 8). Энглвуд Клиффс, Нью-Джерси, США: Прентис Холл . стр. 231 . ISBN  0-13-825001-4 .
  11. ^ Блэкселл, Дэвид (1978). Хогбен, Дэвид; Файф, Деннис В. (ред.). «Связывание записей по битовому шаблону» . Информатика и статистика — Десятый ежегодный симпозиум по интерфейсу . Специальное издание НБС. 503 . Министерство торговли США / Национальное бюро стандартов : 146–156.
  12. ^ Вегнер, Питер (май 1960 г.). «Техника счета единиц в двоичном компьютере» . Коммуникации АКМ . 3 (5): 322. дои : 10.1145/367236.367286 . S2CID   31683715 .
  13. ^ Мула, Войцех; Курц, Натан; Лемир, Дэниел (январь 2018 г.). «Более быстрый подсчет населения с использованием инструкций AVX2». Компьютерный журнал . 61 (1): 111–120. arXiv : 1611.07612 . дои : 10.1093/comjnl/bxx046 . S2CID   540973 .
  14. ^ Стерн и Махмуд, Проектирование систем связи , Prentice Hall , 2004, стр. 477 и далее.
  15. ^ «Примечания к выпуску GCC 3.4» . Проект ГНУ .
  16. ^ «Примечания к выпуску LLVM 1.5» . Проект ЛЛВМ .
  17. ^ «Что нового в Python 3.10» . python.org .
  18. ^ «Примечания к выпуску GHC 7.4.1» . Документация ГХК.
  19. ^ «Глава 12.11. Битовые функции — Справочное руководство MySQL 5.0» .
  20. ^ Меткалф, Майкл; Рид, Джон; Коэн, Малькольм (2011). Объяснение современного Фортрана . Издательство Оксфордского университета . п. 380. ИСБН  978-0-19-960142-4 .
  21. ^ Шварц, Джейк; Гревель, Рик (20 октября 2003 г.) [1993]. Библиотека эмулятора HP16C для HP48S/SX . 1.20 (1-е изд.) . Проверено 15 августа 2015 г. (Примечание. Эта библиотека также работает на HP 48G / GX / G+ . Помимо набора функций HP-16C, этот пакет также поддерживает вычисления для двоичных, восьмеричных и шестнадцатеричных чисел с плавающей запятой в экспоненциальном представлении в дополнение к обычным десятичным числам. числа с плавающей запятой.)
  22. ^ Бонин, Уолтер (2019) [2015]. Руководство пользователя WP 43S (PDF) . 0,12 (проект ред.). п. 135. ИСБН  978-1-72950098-9 . Проверено 5 августа 2019 г. [ постоянная мертвая ссылка ] [1] [2] (314 страниц)
  23. ^ Бонин, Уолтер (2019) [2015]. Справочное руководство WP 43S (PDF) . 0,12 (проект ред.). стр. XIII, 104, 115, 120, 188. ISBN.  978-1-72950106-1 . Проверено 5 августа 2019 г. [ постоянная мертвая ссылка ] [3] [4] (271 страница)
  24. ^ Мартин, Анхель М.; МакКлюр, Грег Дж. (5 сентября 2015 г.). «Модуль эмулятора HP16C для HP-41CX — Руководство пользователя и QRG» (PDF) . Архивировано (PDF) из оригинала 27 апреля 2017 г. Проверено 27 апреля 2017 г. (Примечание. Помимо набора функций HP-16C , эта специальная библиотека для HP-41CX расширяет функциональность калькулятора примерно на 50 дополнительных функций.)
  25. ^ Мартин, Анхель М. (07 сентября 2015 г.). «HP-41: доступен новый эмулятор HP-16C» . Архивировано из оригинала 27 апреля 2017 г. Проверено 27 апреля 2017 г.
  26. ^ Торнгрен, Хокан (10 января 2017 г.). «Документация по божьей коровке» (выпуск 0А изд.) . Проверено 29 января 2017 г. [5]
  27. ^ «Доступен новый модуль HP-41: Божья коровка» . 10 января 2017 г. Архивировано из оригинала 29 января 2017 г. Проверено 29 января 2017 г.
  28. ^ Дейл, Пол; Бонин, Уолтер (2012) [2008]. «Руководство пользователя WP 34S» (PDF) (изд. 3.1) . Проверено 27 апреля 2017 г.
  29. ^ Бонин, Уолтер (2015) [2008]. Руководство пользователя WP 34S (изд. 3.3). Независимая издательская платформа CreateSpace. ISBN  978-1-5078-9107-0 .
  30. ^ «Документация по Free Pascal popcnt» . Проверено 7 декабря 2019 г.
  31. ^ «JDK-6378821: bitCount() должен использовать POPC на процессорах SPARC и AMD+10h» . База данных ошибок Java . 30 января 2006 г.
  32. ^ Справочник по набору инструкций Blackfin (предварительное издание). Аналоговые устройства . 2001. стр. 8–24. Номер детали 82-000410-14.
  33. ^ Вольф, Клэр (22 марта 2019 г.). Расширение битовых манипуляций RISC-V «B» для RISC-V, черновик v0.37» (PDF) . Гитхаб .

Дальнейшее чтение

[ редактировать ]
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 180ccc984ddd4f2bb547fcf635eecc06__1717338840
URL1:https://arc.ask3.ru/arc/aa/18/06/180ccc984ddd4f2bb547fcf635eecc06.html
Заголовок, (Title) документа по адресу, URL1:
Hamming weight - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)