VAR | = 1 << 2;reverisble? - PullRequest
       5

VAR | = 1 << 2;reverisble?

2 голосов
/ 09 марта 2012

Во-первых, я не уверен, что происходит в этой побитовой операции.Я получаю код, написанный и поставляю другим сторонам в виде фрагментов кода.

Теперь, если VAR - 8-разрядное целое число без знака (без знака), а r равно 0 или 1, или 2, или 4. Может быть обратное, если значениеr известно, и полученное значение там. VAR | = 1 << r; </strong> // это 200, где VAR было 192, а r было 3

Например, начальное значение VAR составляет 192 и значение r равно 3 * результат равен 200 *.

Теперь, если у меня есть это 200 , и я знаю значение r это было 3, Могу ли я вернуть его обратно к 192?

Я надеюсь, что это самый простой, но я не знаю этих побитовых операций, так что прости меня.

Спасибо

Ответы [ 5 ]

11 голосов
/ 09 марта 2012

Ответ - нет. Это связано с тем, что оператор | (ИЛИ) не является однозначной функцией .

Другими словами, есть несколько значений VAR, которые могут дать один и тот же результат.

Например:

r = 3;
var0 = 8;
var1 = 0;

var0 |= 1 << r;  //  produces 8
var1 |= 1 << r;  //  produces 8

Если вы попытаетесь инвертировать его, вы не сможете определить, является ли исходное значение 0 или 8.

Аналогичная ситуация применима к оператору & AND.


С точки зрения теории информации:

Операторы | и & несут потерю информации и не сохраняют энтропию данных.

С другой стороны, такие операторы, как ^ (XOR), + и - являются взаимно-однозначными и, таким образом, сохраняют энтропию и являются обратимыми.

6 голосов
/ 09 марта 2012

Нет, OR не является обратимым. Я верю только XOR.

Например, если переменная a содержит 1001 1100 или 1001 1000, а третий бит (справа) установлен равным 1 независимо от начального значения, тогда оба значения 1001 1100 и 1001 1000 в качестве исходных операндов приведет к тому же значению (1001 1100).

1 голос
/ 09 марта 2012

Во-первых, 1 << 2 - это просто еще один способ записи «4» или 100 в двоичном виде. </p>

Оператор | = - это еще один способ записи x = x | у;

Конечный результат - установка бита 2 в х. Если бит 2 в x равен нулю, то в обратном порядке он будет очищать бит 2. Если бит 2 равен 1, то это неоперация.

Проблема вашего вопроса в том, что вы не знаете заранее, каково было начальное состояние бита 2.

Если вашей целью было очистить бит 2, вы можете сделать это:

x &= ~(1<<2);
0 голосов
/ 09 марта 2012

Нет, вы не можете отменить операцию ИЛИ.

В вашем примере при r = 3 оба начальных значения VAR = 192 и VAR = 200 приведут к 200.

Поскольку есть два входных значения, которые дадут одинаковый результат, вы не будете знать, к какому из них вернуться.

0 голосов
/ 09 марта 2012

Учитывая выражение result |= 1 << shiftAmount, соответствующее VAR и r в вашем исходном примере, вы можете использовать следующее, чтобы сделать прямо противоположное:

result &= ~(1 << shiftAmount)

Обратите внимание, что это не чисто обратное, потому что побитовая или не является однозначной функцией. Побитовый или устанавливает один или несколько битов в 1, независимо от того, были ли они уже 0 или 1. Выражение, которое я показал выше, всегда будет устанавливать для связанных битов значение 0, поэтому, если бит был равен 1, он не вернется к исходное состояние.

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