Объяснение алгоритма для установки очистите и протестируйте единственный бит

Вот мои два цента:

  • Попробуйте и импортируйте gmpy2 , если у вас его еще нет.
  • Со страницы проекта, на которую вы ссылались:

    Команда фактора GNU не будет вычислять что-либо большее, чем 2 ^ 127-1

    blockquote>

    примерно 1.7 * 10 ^ 38, значительно меньшее число, чем то, на которое вас "сбрасывают". Таким образом, может быть (я размышляю здесь), что существуют ограничения в этом пакете, и что люди, которые сообщают, что он работает на некоторых ОС (MacOS, на данный момент), также получают некоторую ошибку «dump», которая обрабатывается с помощью ОС на уровне CPython, с некоторыми «ненужными» значениями памяти, заставляя их поверить, что это работает.

5
задан Community 23 May 2017 в 12:26
поделиться

5 ответов

VonC отправил хороший ответ о битовых масках в целом. Вот некоторая информация, это более характерно для кода, который Вы отправили.

Учитывая целое число, представляющее немного, мы удаемся, какой член массива держит тот бит. Это: Биты от 0 до 31 живого в a[0], биты 32 - 63 живых в a[1], и т.д. Все это i>>SHIFT делает i / 32. Это удается который член a бит живет в. С оптимизирующим компилятором они, вероятно, эквивалентны.

Очевидно, теперь мы узнали который член a тот битовый флаг живет в, мы должны удостовериться, что устанавливаем корректный бит в том целом числе. Это что 1 << i делает. Однако мы должны удостовериться, чтобы мы не пытались получить доступ к 33-му биту в 32-разрядном целом числе, таким образом, операция сдвига ограничивается при помощи 1 << (i & 0x1F). Волшебство здесь - это 0x1F 31, таким образом, мы никогда не будем сдвиг влево бит, представленный i больше чем 31 место (иначе это должно было войти в следующего члена a).

7
ответ дан 18 December 2019 в 09:11
поделиться

Когда Вы хотите установить немного в массиве, Вы имеете к

  1. ищите на правильный индекс массива и
  2. установите соответствующий бит в этом объекте массива.

Существуют BITSPERWORD (=32) биты в одном объекте массива, что означает что индекс i должен быть разделен на две части:

  • самые правые 5 битов служат индексом в объекте массива и
  • остальная часть битов (крайние левые 28) служит индексом в массив.

Вы добираетесь:

  • крайние левые 28 битов путем отбрасывания самых правых пяти, который является точно что i>>SHIFT делает, и
  • самые правые пять битов путем каширования чего-либо кроме самых правых пяти битов, которое является что i & MASK делает.

Я предполагаю, что Вы понимаете остальных.

5
ответ дан 18 December 2019 в 09:11
поделиться

Отсюда (Общий ответ для запущения этого потока)

Немного маски является значением (который может быть сохранен в переменной), который позволяет Вам изолировать определенный набор битов в целом типе.

Обычно маскированное будет иметь биты, Вы интересуетесь набором к 1 и все другие биты набор к 0. Маска затем позволяет Вам изолировать значение битов, очищать все биты или устанавливать все биты или устанавливать новое значение к битам.

Маски (особенно многоразрядные) часто имеют связанное значение сдвига, которое является суммой, битам нужно смещение, оставленное так, чтобы младший значащий бит маскированный был смещен к младшему значащему биту в типе.

Например, использование короткого типа данных на 16 битов предполагает, что Вы хотели смочь замаскировать биты 3, 4 и 5 (LSB является номером 0). Вы маскируете, и сдвиг посмотрел бы что-то как

#define MASK 0x0038
#define SHIFT 3

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

Если у меня есть переменная, var, который содержит данные, для которых маска относится затем, я могу изолировать биты как это

var & MASK

Я могу изолировать все другие биты как это

var & ~MASK

Я могу очистить биты как это

var &= ~MASK;

Я могу очистить все другие биты как это

var &= MASK;

Я могу установить все биты как это

var |= MASK;

Я могу установить все другие биты как это

var |= ~MASK;

Я могу извлечь десятичное значение битов как это

(var & MASK) >> SHIFT

Я могу присвоить новое значение битам как это

var &= ~MASK;
var |= (newValue << SHIFT) & MASK;
6
ответ дан 18 December 2019 в 09:11
поделиться

Битовая операция и ведущие абзацы Маски являются кратким объяснением и содержат некоторые указатели для дальнейшего исследования.

Думайте о 8-разрядном байте как о ряде элементов от вселенной с 8 участниками. Участник находится В наборе, когда соответствующий бит установлен. Установка немного больше затем однажды не изменяет членство в наборе (немного может иметь только 2 состояния). Побитовые операторы в C обеспечивают доступ вдребезги путем маскирования и смещения.

0
ответ дан 18 December 2019 в 09:11
поделиться

Код пытается сохранить N биты массивом, где каждый элемент массива содержит BITSPERWORD (32) биты.

Таким образом, при попытке получить доступ к биту i, необходимо вычислить, индекс элемента массива хранит его (i/32), который является что i>>SHIFT делает.

И затем необходимо получить доступ к тому биту в элементе массива, который мы просто получили.

(i & MASK) дает позицию двоичного разряда в элементе массива (слово). (1<<(i & MASK)) делает бит в том положении, которое будет установлено.

Теперь можно устанавливать/очищать/тестировать тот бит в a[i>>SHIFT] (1<<i & MASK)).

Можно также думать i число на 32 бита, что биты 6~31 являются индексом элемента массива, хранит его, биты 0~5 представляет позицию двоичного разряда в слове.

0
ответ дан 18 December 2019 в 09:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: