сдвиг битов - замена части набора битов новым номером - PullRequest
2 голосов
/ 29 марта 2011

У меня есть список чисел, закодированных как динамический битовый импульс повышения.Я динамически выбираю размер этого набора битов в зависимости от максимального значения, которое может принимать любое число в этом списке.Допустим, у меня есть числа от 0 до 7, мне нужно всего три бита, и моя строка 0,2,7 будет закодирована как 000010111.

Теперь мне нужно изменить, скажем, 2-е число в этом списке (2) на другое число, скажем 4. Я подумал, что наиболее эффективный способ сделать это - представить 4 в виде динамического набора битов той же длины, что и список, но со всеми другими значениями, установленными в 1, поэтому 111111011.Затем я бы сдвинул это требуемое количество битов, используя 1, чтобы заполнить значения, чтобы получить 111011111, а затем просто поразрядно И это с исходным набором битов, чтобы получить желаемый результат.

Однако я не могу найтиспособ сделать эти две вещи, как это выглядит как при инициализации набора битов из целого числа, так и при сдвиге битов, значения по умолчанию и значения заполнения всегда устанавливаются в 0, а не в 1. Как я могу обойти эту проблему или добитьсямоя цель по-другому и эффективно.

Спасибо

Ответы [ 4 ]

2 голосов
/ 29 марта 2011

Если это действительно реализация, то самый общий и эффективный метод, который я могу придумать, состоит в том, чтобы сначала замаскировать все биты для заменяемой части:

value &= 111000111;

Затем "или" в фактических битах для этой позиции:

value |= 000011000;

Надеюсь, у кого-то здесь есть лучший трюк для меня, но я так и делаю.

1 голос
/ 29 марта 2011

XOR старого значения и нового значения:

int valuetoset = oldvalue ^ newvalue;  // 4 XOR 2 in your example

Просто сдвиньте значение, которое вам нужно установить:

int bitstoset = valuetoset << position; // (4 XOR 2) << 3 in your example

Затем снова выполните XOR bittoset с вашим bitset и все!

int result = bitstoset ^ bitset;
0 голосов
/ 29 марта 2011

Я полагаю, что ваше понимание набора битов элементарно неверно: set означает, что он НЕ упорядочен, и идея набора битов состоит в том, что для показа того, что элемент находится внутри / вне набора, необходим только один бит.Таким образом, ваш исходный набор 0,2,7 будет иметь 8 битов, потому что 0..7 - это 8 элементов, а НЕ 3 * 3 (3 бита, необходимых для представления 0..7), а растровое изображение будет выглядеть как 10000101.То, что вы описываете, это просто «упакованная» кодировка значений.В вашей схеме кодирования 0,2,7 и 2,0,7 будут закодированы совершенно по-разному, но в битовом наборе они одинаковы.

В (реальном) битовом наборе (если это то, что вы хотите) выЗатем можно действительно легко «заменить» элементы, удалив старые и добавив новые.Это происходит так, как описывает TED.

Чтобы получить правильную маску, вы можете легко использовать операции сдвига.Итак, представьте, что вы начинаете считать с 0, вы получаете маску для значения x, выполняя: 1<<x;

Таким образом, вы удаляете элемент x из набора с помощью

value &= ~(1<<x);

и добавляете еще один элементx (который может быть таким же) с

value | = 1<<x;

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

Команда с битовой маской для удаления элемента в позиции p:

value &= ~(111 p);

Это 111 для приведенного выше примера, где вам нужно 3 бита для позиции.Если вы не хотите жестко его кодировать, вы можете просто взять следующую степень 2 и вычесть 1, а затем вы получите свою единственную 1-строковую строку.

И для добавления вы просто возьмете свой самый подходящий битлист, содержащийтолько новый элемент и ИЛИ его в ваш список битов:

value |= new_element_bitlist;
0 голосов
/ 29 марта 2011

Сможете ли вы использовать vector динамических битовых наборов?В зависимости от ваших потребностей этого может быть достаточно, чтобы можно было легко обновлять.

Поочередно наполняйте свой новый набор битов примерно так же, как вы предлагали, но в точности перевернули.Затем, перед тем как вы сделаете и в конце, переверните все биты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...