Как удалять биты целого числа?

У меня есть следующая школьная проблема:

Данные десятичный n и положение k возвращать десятичное число без k-ésimo бит, а именно, если n=37 и k=3, нужно возвращаться 33. Проблема, которая состоит в том, что они обусловили меня, отвечать это в единственной линии, (Первоначальная проблема - codefights, как кажется, и только возможно изменять return), у меня нет большого количества опыта в управлении бит и я засорен, кодирую в C ++.

1
задан 09.10.2016, 05:41
5 ответов

У каждого числа есть бинарное представление. Я верю в это, что все это знаем. Если мы хотим удалить бит X, мы должны применять операцию AND на вышеупомянутом бите. Способ это получать состоит в том, чтобы создавать маску бит, в которой все положения содержат один 1 за исключением положения, которое нужно удалять, в которой будет находиться один 0.

Пример, чтобы удалять 2-ой бит

int numero = 150;
int mask = 0xFFFFFFFD; // 0xD = 1101
int resultado = numero & mask;
std::cout << resultado; // imprime 148

Если мы сейчас это хотим сделать dinámicamente вещь, он осложняется немного.

Очень полезное уравнение, чтобы менять бит, который мы желаем:

resultado = numero ^ ((-nuevoValorDelBit ^ numero) & (1 << indiceDelBit));

Где:

  • nuevoValorDelBit смоги стоить 0 или 1.
  • indiceDelBit это положение бита. Помни, что индексы начинаются в 0.

Принесенный это в наш код:

int numero = 150;
int bitABorrar = 1; // el 2º bit
int resultado = numero ^ (numero & (1 << bitABorrar));  

Чтобы понимать это уравнение лучшее состоит в том, чтобы брать карандаш и бумагу:

numero = 150 = 1001 0110
A = 1 << bitABorrar = 1 << 1 = 0010
B = numero & (1 << bitABorrar) = numero & A = 1001 0110 & 0010 = 0010
C = numero ^ (numero & (1 << bitABorrar)) = numero ^ B = 1001 0110 ^ 0010 = 1001 0100
resultado = C = 1001 0100 = 148
6
ответ дан 24.11.2019, 13:16
  • 1
    Спасибо, твой ответ я разъясняю себе то, что нужно делать, и операции, которые нужно использовать, ты достал меня из сомнений, я должен изучать больше этих операций на уровне бит. –  Elias Segundo 30.09.2016, 03:13

Обрати внимание 37 в бинарном он 100101 и 33 100001 действительно то, что они делают, состоит в том, чтобы помещать третий бит в 0 это ты это делаешь применяя маску... А именно делая один & с известным числом.

А именно ты нуждаешься в том, чтобы сделать операцию & бит в бит с 111011 ... сейчас, как числа больше в зависимости от представления хардвера, где он прокрутил изображение в окне (16bits, 32 бита или 64bits) ты не знаешь все те 1 у тебя есть наполнения следовательно я recomiento делать отрицание 4 что 000000100 с битами наоборот....

 int c = 37;
 return c & (~4);
1
ответ дан 24.11.2019, 13:16
  • 1
    Это включенный м и # 225; s f и # 225; cil используя буквальных бинарных C ++ 14: int c = 0b100101; return c & 0b111011; –  PaperBirdMaster 29.09.2016, 11:03
  • 2
    Спасибо, с твоим решением и решением eferion я у себя остаюсь ясным тема, это что-то редкое, из-за чего никогда он не использовал эти операторы, но сейчас я понимаю лучше. –  Elias Segundo 30.09.2016, 03:16

return n & ~(1 << (k-1)) он делает то, что ты ищешь.

Я рекомендую тебе перечитывать изложение проблемы; в этом типе операций, для k обычно считают, что Вашей первой стоимости 0, так что (k-1) он остался бы просто как k (и результат для (n, k) = (37, 3) не было бы 33, а 37). Действительно, с карандашом и бумагой он проще понимания.

Операторы << и >> они перемещают стоимость в левую сторону или правую сторону (они умножают или делят из-за 2). В этом случае мы начинаемся с 1 и это перемещаем в левую сторону k-1 биты. Уже у нас есть 1 на бите n который мы хотим изменить.

Поскольку которое мы хотим сделать, он состоит в том, чтобы помещать бит 0, мы используем ~ чтобы отказывать в 1 0 и оставшейся части бит, poniéndo этот 1. Потом, сделав & с n мы пропустим биты, которые соответствуют с 1 из нашей маски, оставляя 0, которые нет.

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

return ~(~n | (1 << (k-1))). Ты понимаешь почему?

1
ответ дан 24.11.2019, 13:16

В одной lГ-nea, в действительности он не удаляет бит, только это помещает в нуль, говорится mГєltiplos о 2.

int k=3,n=37; n-=k==1?1:k==2?2:k==3?4:k==4?8:k==5?16:k==6?32:k==7?64:k==8?128:0;
1
ответ дан 24.11.2019, 13:16

return n & ~ (1 < < k);

Часть izda "n" тривиальная

Прямая часть - способ помещать бит 0 в C:

& ~ (1 < < k)

0
ответ дан 24.11.2019, 13:16