#bit-manipulation #bitwise-operators
Вопрос:
Начиная с позиции 1 бита высшего порядка, как я могу отрицать этот бит и все биты более низкого порядка?
Пример (C#)
int inputNumber = 0b_10001;
inputNumber = ~inputNumber; // bitwise complement
int expectedNumber = 0b_000000000000000000000000000_01110;
uint actualNumber = 0b_111111111111111111111111111_01110; // almost, but not quite
Подробные сведения
0b
это просто маркер, чтобы начать писать число в двоичном формате. Это _
просто разделитель, чтобы визуально было легче следовать (но все еще действительный код C#). Пример: 0b_1010_1111
на самом деле 10101111
в двоичном формате.
Я чувствую, что близок к решению — мне нужно сделать маску, чтобы избавиться от нежелательных кусочков, но я не уверен, как это сделать.
Как я могу перейти от 10001
к 01110
, в основном отрицая каждый бит, но не имея ведущих 1
s?
Комментарии:
1. @njuffa, эта маска будет работать только для этого конкретного номера, а не для всех из них. Я должен посчитать количество установленных битов и иметь маску только для них, но все еще не могу понять, как это сделать.
2. Этот распространенный метод построения непрерывной маски справа создаст непрерывную группу из 1 бита справа от наиболее значимого 1 бита, вплоть до бита 0. Пример:
0b_10001
превратится в0b_11111
. Я предполагаю четко определенный оператор сдвига вправо, что в C и C означает, что вы захотите использоватьunsigned
целочисленный тип для этих данных. Я не знаю, как C# определяет правильные сдвиги, в частности, с потенциально отрицательными целочисленными типами со знаком. Установив маску, вы можете затем использовать(0 - x) amp; m
ее для выполнения нужного отрицания битового поля.3. @njuffa, я попробовал маску из твоего первого комментария, но вместо этого я получаю
11101
11111
. Второй бит не установлен (я использовал unsigned и C ). Пример онлайн: cpp.sh/7ipif4. Извини, я виноват. Правильный код:
m = x; m = m | (m >> 16); m = m | (m >> 8); m = m | (m >> 4); m = m | (m >> 2); ; m = m | (m >> 1);
5. @njuffa, вау, это работает! Спасибо! Хотели бы вы опубликовать ответ, чтобы я мог проголосовать и согласиться отдать вам должное за вашу помощь?