Что значит инвертируем все биты числа
Перейти к содержимому

Что значит инвертируем все биты числа

  • автор:

Как инвертировать только определённые биты в числе

Мне нужно инвертировать все биты в числе, допустим, 2 ( 10 в двоичной системе) после инвертирования будет равно 01 . Но столкнулся с проблемой, что операция побитового отрицания инвертирует также и знаковый бит и вообще все биты, которыми число представлено в памяти. И получается, что:

int a = ~2; // -3 

Как мне всё-таки получить 1 , а не -3 ?
Отслеживать
28.5k 12 12 золотых знаков 58 58 серебряных знаков 118 118 бронзовых знаков
задан 8 фев 2019 в 7:31
IWProgrammer IWProgrammer
831 1 1 золотой знак 15 15 серебряных знаков 28 28 бронзовых знаков
как же так, 2 — это . 00010 после инвертирования будет. 11101. Поставьте явную задачу
8 фев 2019 в 7:45

5 ответов 5

Сортировка: Сброс на вариант по умолчанию

Вообще-то битовые операции не стоит применять к знаковым целым числам, поэтому я пишу сразу для unsigned .

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

000010000101 -> 000001111010 000011111111 -> 000000000000 
unsigned int inv(unsigned int x) < unsigned int mask = 0; for(unsigned int y = x;y;y>>=1) (mask

Здесь для 0 все же инвертируем его в 1.

Но вот не уверен, что вы хотите для 7 или там 3 инвертирование в 0 — все их единички.

А вообще — нужно очень точное ТЗ, иначе результатом будет ХЗ.

С тем же успехом, для @avp:

 mov eax, d bsr ecx, eax inc ecx mov ebx, 1 shl ebx, cl dec ebx dec ebx or ebx, 1 xor d, ebx 

Что значит инвертируем все биты числа

Здравствуйте.
Вот осваиваю побитовые операции, столкнулся с проблемой: как проверить установлен ли N’ный бит и как его установить, снять?
И может кто знает, где почитать что-нибудь по теории работы на битовом уровне? Я уже кучу сайтов пролазил, почти везде дальше пары абзацев по побитовым операторам не заходит.

Re: Побитовые операции

От: Алекс Пронскявичус
Дата: 06.08.02 00:48
Оценка:

Сорри, на первый вопрос ответ нашел в архиве.
Re: Побитовые операции

От: Dr_Sh0ck
Дата: 06.08.02 04:49
Оценка: 7 (2)

Здравствуйте Алекс Пронскявичус, Вы писали:

АП>Здравствуйте.
АП>Вот осваиваю побитовые операции, столкнулся с проблемой: как проверить установлен ли N’ный бит и как его установить, снять?

Я так понял, ответ на первый вопрос ты нашел.

Устанавливается бит операцией OR (логичексое сложение): первым операндом является переменная, где ты хочешь установить бит(ы), а вторым операндом — число, в котором нужные для установки в первом числе биты выставлены в 1:

char c; c |= 1; // устанавливает 0-ой бит в с с |= 2; // устанавливает 1-ый бит в с c |= 3; // устанавливает 0-ой и 1-ый биты в с

и т.д. по степеням двойки

«сбрасываеся» в 0 бит операцией AND (логическое умножение): первым операндом является переменная, где ты хочешь сбросить бит(ы), а вторым операндом — число, в котором нужные для сброса в первом числе биты выставлены в 0:

char c; c &= 1; //сбрасывает 0-ой бит в с с &= 2; // сбрасывает 1-ый бит в с c &= 3; // сбрасывает 0-ой и 1-ый биты в с

Чтобы инвертировать (изменить значение на противоположное — 0 на 1; 1 на 0) бит(ы) проименияется операция XOR (исключение ИЛИ): первым операндом является переменная, где ты хочешь инвертировать бит(ы), а вторым операндом — число, в котором нужные для инверсии в первом числе биты выставлены в 1:

char c; c ^= 1; //инвертирует 0-ой бит в с с ^= 2; //инвертирует 1-ый бит в с c ^= 3; //инвертирует 0-ой и 1-ый биты в с

АП>И может кто знает, где почитать что-нибудь по теории работы на битовом уровне? Я уже кучу сайтов пролазил, почти везде дальше пары абзацев по побитовым операторам не заходит.

Вообщем, любая книга по ассемблеру, большинтсво книг по С.

Do not fake yourself 😉
ICQ#: 198114726
Re[2]: Побитовые операции

От: ppp
Дата: 06.08.02 05:20
Оценка: 20 (4)

Здравствуйте Dr_Sh0ck, Вы писали:

DS>»сбрасываеся» в 0 бит операцией AND (логическое умножение): первым операндом является переменная, где ты хочешь сбросить бит(ы), а вторым операндом — число, в котором нужные для сброса в первом числе биты выставлены в 0:
DS>

DS>char c; DS>c &= 1; //сбрасывает 0-ой бит в с DS>с &= 2; // сбрасывает 1-ый бит в с DS>c &= 3; // сбрасывает 0-ой и 1-ый биты в с DS>

С этим я не согласен. Операция

b &= flag

оставляет только те биты в байте b, которые совпадают и в байте и во флаге. Например,

10 & 8 = 8, тк в двоичной записи это выглядит так
1010 & 1000 = 1000

10 & 1 = 0, тк в двоичной записи это выглядит так
1010 & 0001 = 0000

Сбросить в 0 нужный бит можно следующей операцией
b &= ~flag (~ это инвертирование байт в бите)

сбрасываем 4й бит
10 & ~8 = 2, тк в двоичной записи это выглядит так
1010 & ~1000 = 1010 & 0111 = 0010

сбрасываем 2й и 3й биты (флаг = 6)
10 & ~6 = 8, тк в двоичной записи это выглядит так
1010 & ~0110 = 1010 & 1001 = 1000

От себя порекомендую следующие очень полезные битовые операции:
>> — сдвиг вправо

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

int c = 10;
c >>= 2 даст в результате 2, но

int d = -10;
d >>= 2 даст в результате 0xfffffffd (существует правило, что знаковые целые при сдвиге вправо заполняются слева единицами)

если же пользоваться беззнаковыми целыми, то все прозрачно
unsigned u = -10; //0xfffffff6
u >>= 2 даст в результате 0x3ffffffd

Если ты такой умный, почему ты такой бедный?
Re[3]: Побитовые операции

От: Dr_Sh0ck
Дата: 06.08.02 06:09
Оценка:

Здравствуйте ppp, Вы писали:

ppp>Здравствуйте Dr_Sh0ck, Вы писали:

DS>>»сбрасываеся» в 0 бит операцией AND (логическое умножение): первым операндом является переменная, где ты хочешь сбросить бит(ы), а вторым операндом — число, в котором нужные для сброса в первом числе биты выставлены в 0:
DS>>

DS>>char c; DS>>c &= 1; //сбрасывает 0-ой бит в с DS>>с &= 2; // сбрасывает 1-ый бит в с DS>>c &= 3; // сбрасывает 0-ой и 1-ый биты в с DS>>

ppp>С этим я не согласен. Операция

Ну, конечно, блин, опозорился. Это я так хотел ответить побыстрее
Операции вставки/копирования, конечно, удобны, но иногда неплохо все вручныю писАть — еньше шансов на вот такие глупые ошибки.

P.S. Кто сильно матерился на мой ответ, прошу прощения

Do not fake yourself 😉
ICQ#: 198114726
Re: Побитовые операции

От: Аноним
Дата: 06.08.02 06:15
Оценка:

Здравствуйте Алекс Пронскявичус, Вы писали:

АП>Здравствуйте.
АП>Вот осваиваю побитовые операции, столкнулся с проблемой: как проверить установлен ли N’ный бит и как его установить, снять?
АП>И может кто знает, где почитать что-нибудь по теории работы на битовом уровне? Я уже кучу сайтов пролазил, почти везде дальше пары абзацев по побитовым операторам не заходит.

const unsigned char bitMask = 0b00100000;
unsigned char yourVar;

Re[2]: Побитовые операции

От: Аноним
Дата: 06.08.02 06:31
Оценка:

Здравствуйте Аноним, Вы писали:

А>Здравствуйте Алекс Пронскявичус, Вы писали:

АП>>Здравствуйте.
АП>>Вот осваиваю побитовые операции, столкнулся с проблемой: как проверить установлен ли N’ный бит и как его установить, снять?
АП>>И может кто знает, где почитать что-нибудь по теории работы на битовом уровне? Я уже кучу сайтов пролазил, почти везде дальше пары абзацев по побитовым операторам не заходит.

А>const unsigned char bitMask = 0b00100000;

А это где такое бывает?

Re[2]: Побитовые операции

От: Алекс Пронскявичус
Дата: 06.08.02 07:21
Оценка:

Здравствуйте Dr_Sh0ck, Вы писали:

DS>Вообщем, любая книга по ассемблеру, большинтсво книг по С.

Ага! В книгах по С тоже есть, а я уж думал придётся читать что-то по ассемблеру.

Re[3]: Побитовые операции

От: Алекс Пронскявичус
Дата: 06.08.02 07:21
Оценка:

Здравствуйте ppp, Вы писали:

Битовое представление чисел и операции с ними

Допустим, есть задача, сформулированная следующим образом: >. Первым делом мы зададим вопрос, а где у числа первый бит? Если бы вопрос был сформулирован в терминах страших/младших битов, то все сомнения бы отпали.

Дело в том, что может быть и так, и так. В зависимости от архитектуры операционной системы порядок бит при записи их в памяти будет разным. Различают big-endian и little-endian.

При схеме little-endian сначала идут младшие биты. Например, число $100_$ записывалось в двоичной записи так: $0010011$.

При записи в формате big-endian сначала идут старшие биты. В абзаце выше все примеры даны в big-endian формате.

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

  1. Внимательно посмотреть на тесты и попробовтаь определить из них формат.
  2. Только в случае, если предыдущий шаг не сработал, обратиться к преподавателям за дополнительным примером.

Операции с битами

  • a & b = 1 $\Leftrightarrow$ a = 1 и b = 1. AND
  • a | b = 1 $\Leftrightarrow$ a = 1 или b = 1. OR
  • a ^ b = 1 $\Leftrightarrow$ $a \neq b$. XOR
  • ~a = 0 $\Leftrightarrow$ a = 1, ~a = 1 $\Leftrightarrow$ a = 0. Инверсия бита
  • $13$ & $7$ = $1101_2$ & $0111_2$ = $0101_2$ = $5$
  • $17$ | $10$ = $10001_2$ | $01010_2$ = $11011_2$ = $27$
  • $17$ ^ $9$ = $10001_2$ ^ $01001_2$ = $11000_2$ = $24$

Выделить i-й бит числа

Сразу скажем, что $i$-й, начиная с младших бит, нумерация с нуля. Пусть исходное число равно $A$.

выделить 2-й бит в числе 21:

Выставить i-й бит числа в единицу

То есть надо сделать так, что на $i$-й позиции битовой записи числа стояла единица.

Инвертировать все биты числа

Получить число, состоящее из k единиц

Если такое число сдвинуть на несколько битов влево, то получим маску из $k$ единиц, которой можно выделять (с помощью побитового «И») произвольные k бит числа.

Автор конспекта: Полина Романченко

По всем вопросам пишите в telegram @Romanchenko

C/C++ Работа с битами

В Си существуют 6 операторов для манипулирования битами:

>> — сдвиг вправо
~ — поразрядная инверсия
| — поразрядное ИЛИ
& — поразрядное И
^ — поразрядное исключающее ИЛИ

Если нужно записать сразу несколько бит:

unsigned char x = 0; x = 1

Номера битов отсчитываются справа налево, начиная с нуля. 0 — это младший бит (справа), 7 — это старший бит (слева).

Если нужно записывать определенные биты, не стирая другие:

Чтобы записать единицу в бит n:

x |= (1 

Чтобы записать ноль в бит n:

x &= ~(1 

Если нужно инвертировать состояние бита:

x ^= (1 

Если нужно прочитать отдельный бит:

unsigned char x = (1 if (x & (1 /* во второй бит вписана единица */ > if (x & (1 /* в третий бит вписана единица */ > if (x & (1 /* в седьмой бит вписана единица */ >

Если нужно определить, что в X на N-й позиции:

bool b = (bool((1 

Если нужно обнулить один или несколько битов:

Для обнуления отдельных битов используется оператор &

int x = 58; // 00111010 int y = x & 0x0F; // 00001010

Обнулить несколько битов можно и так:

x = x & (~((1<<3)|(1<<5)|(1<<6))); //обнуляем третий, пятый и шестой биты

Если нужно установить заданные биты в единицу. Используют оператор |

int x = 155 x = x | 4; //устанавливаем в единицу второй бит переменной x
155 0b10011011 | 4 0b00000100 159 0b10011111

Сдвиг влево

Сдвигает число на n разрядов влево

unsigned char x = 3; //0b00000011 x = x //0b00011000 (24)

Сдвиг вправо >>

Сдвигает число на n разрядов вправо

unsigned char x = 255; //0b11111111 x = x >> 3; //0b00011111 (31)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *