Вот мои два цента:
Со страницы проекта, на которую вы ссылались:
Команда фактора GNU не будет вычислять что-либо большее, чем 2 ^ 127-1
blockquote>примерно 1.7 * 10 ^ 38, значительно меньшее число, чем то, на которое вас "сбрасывают". Таким образом, может быть (я размышляю здесь), что существуют ограничения в этом пакете, и что люди, которые сообщают, что он работает на некоторых ОС (MacOS, на данный момент), также получают некоторую ошибку «dump», которая обрабатывается с помощью ОС на уровне CPython, с некоторыми «ненужными» значениями памяти, заставляя их поверить, что это работает.
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
).
Когда Вы хотите установить немного в массиве, Вы имеете к
Существуют BITSPERWORD
(=32) биты в одном объекте массива, что означает что индекс i
должен быть разделен на две части:
Вы добираетесь:
i>>SHIFT
делает, и i & MASK
делает. Я предполагаю, что Вы понимаете остальных.
Отсюда (Общий ответ для запущения этого потока)
Немного маски является значением (который может быть сохранен в переменной), который позволяет Вам изолировать определенный набор битов в целом типе.
Обычно маскированное будет иметь биты, Вы интересуетесь набором к 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;
Битовая операция и ведущие абзацы Маски являются кратким объяснением и содержат некоторые указатели для дальнейшего исследования.
Думайте о 8-разрядном байте как о ряде элементов от вселенной с 8 участниками. Участник находится В наборе, когда соответствующий бит установлен. Установка немного больше затем однажды не изменяет членство в наборе (немного может иметь только 2 состояния). Побитовые операторы в C обеспечивают доступ вдребезги путем маскирования и смещения.
Код пытается сохранить 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 представляет позицию двоичного разряда в слове.