Я наткнулся на следующий фрагмент кода
if( 0 != ( x ^ 0x1 ) )
encode( x, m );
Что x ^ 0x1
значит? Это какая-то стандартная техника?
c++
c
bit-manipulation
bitmask
KodeWarrior
источник
источник
0 != (x ^ 1)
→ xor с обеих сторон на 1 →(0 ^ 1) != (x ^ 1 ^ 1)
→ упрощение →1 != x
if (1 != x)
сложно писать.type
ofx
не задан - следовательно, мы не знаем, что это целое число в этой теговой проблеме C ++. Конечно, если это C илиx
целое число, ответ прост, но это не дано, иoperator ^
существует вероятность перегрузки .Ответы:
Операция XOR (
x ^ 0x1
) инвертирует бит 0. Таким образом, выражение фактически означает: если бит 0 в x равен 0 или любой другой бит в x равен 1, то выражение является истинным.И наоборот, выражение ложно, если x == 1.
Итак, тест такой же как:
и поэтому (возможно) излишне запутывается.
источник
^
это побитовая операция XOR0x1
находится1
в шестнадцатеричном видеx ^ 0x1
будет инвертировать последний битx
(обратитесь к таблице истинности XOR по ссылке выше, если это вам не понятно).Таким образом, условие
(0 != ( x ^ 0x1 ))
будет истинным, еслиx
оно больше 1 или последний битx
равен 0. Это оставляет только x == 1 в качестве значения, при котором условие будет ложным. Так что это эквивалентноPS Адский способ реализации такого простого условия, я мог бы добавить. Не делай этого. И если вам нужно написать сложный код, оставьте комментарий . Я прошу тебя.
источник
x==0
;4 ^ 0x1
верно, но4==0
очевидно ложно.if (x == 0)
», не так лиx != 1
?x
это целочисленный тип. Если этоfloat
илиdouble
, то я считаю, что выражение даст истинное значение для1.0 <= x < 2.0
. И еслиx
это пользовательский тип, выражение может возвращать true, еслиx
это день рождения юго, кенгуру, знаменитого композитора или любое число, которое разделяет не менее трех цифр с текущей долларовой ценой чая в Китае.operator^
дляfloat
/double
.Это может показаться упрощенным объяснением, но если кто-то хотел бы пройти через это медленно, оно ниже:
^
является побитовым оператором XOR в c, c ++ и c #.Таблица истинности в виде исключающего Ь :
Итак, давайте проиллюстрируем
0 == ( x ^ 0x1 )
выражение на двоичном уровне:так:
источник
Это эксклюзивный оператор OR (XOR). Чтобы понять, как это работает, вы можете запустить этот простой код
Выход будет
Так что это выражение
будет равен true только тогда, когда x! = 0x1.
Это не меняет сам х. Он только проверяет, равен ли х 0 или 1. это выражение может быть изменено на
источник
Он проверяет , что
x
на самом деле не0x1
...xor
ИНГx
с0x1
приведет к 0 , только еслиx
это0x1
... это старый трюк в основном используется на языке ассемблераисточник
!= 1
?xor
подход содержал меньше машинный код и выполняется быстрее , чем соответствующие присвоения0
... Однако этот вопрос содержитxor
и сравнение, так что я мог думать , что!=
может быть Быстрее. Однако я не уверен, что нужно будет увидеть сборку, сгенерированную компилятором.^
Оператор поразрядного исключающего. И0x1
это число1
, записанное в виде шестнадцатеричной константы.Таким образом,
x ^ 0x1
оценивается новое значение, которое совпадаетx
, но с переброшенным младшим значащим битом.Код не более чем сравнивает x с 1 очень запутанным и неясным способом.
источник
Оператор xor (исключающий или) чаще всего используется для инвертирования одного или нескольких битов. Операция заключается в том, чтобы спросить, является ли один из битов одним, это приводит к следующей таблице истинности (A и B - входные данные, Y - выходные данные):
Теперь цель этого кода, кажется, состоит в том, чтобы проверить, является ли последний бит равным 1, а остальные равны 0, это равно
if ( x != 1 )
. Причина этого неясного метода может заключаться в том, что ранее использовались методы манипулирования битами и, возможно, они используются в других местах программы.источник
^
поразрядноxor operator
вc
. В вашем случае x имеет xor'ed с 1. Например,x
имеет значение 10, тогда10d ^ 1d ===> 1010b ^ 0001b = 1011b, 1011b == 11d
условие становится истинным.источник
10 != 1010
10 (decimal) == 1010 (binary)
b
или что-то еще?Побитовый тест кажется преднамеренным запутыванием, но если лежащие в основе данные являются корпоративными данными из системы мэйнфреймов IBM, то может просто оказаться, что код написан для отражения оригинальной документации. Форматы данных IBM восходят к 1960-м годам и часто кодируют флаги как отдельные биты в слове, чтобы сэкономить память. Поскольку форматы были изменены, байты флага были добавлены в конце существующих записей для обеспечения обратной совместимости. Например, документация для записи SMF может содержать код на языке ассемблера для проверки трех отдельных битов в трех разных словах в одной записи, чтобы определить, что данные являются входным файлом. Я знаю гораздо меньше о внутренностях TCP / IP, но вы также можете найти там битовые флаги.
источник
Оператор ^ является побитовым xor (см. &, |). Результат для битовой пары:
Итак, выражение,
инвертирует / переворачивает 0-й бит x (оставляя остальные биты без изменений).
Подумайте, может ли x иметь значения помимо 0x0 и 0x1? Когда x является однобитовым полем, оно может иметь только значения 0x0 и 0x1, но когда x является целым (char / short / long / etc), биты, кроме bit0, могут влиять на результат выражения.
Выражение в том виде, в котором оно дано, позволяет битам около бит 0 влиять на результат,
Который имеет эквивалентную правдивость как это (более простое) выражение,
Обратите внимание, что это выражение будет проверять только бит 0,
Таким образом, выражение в том виде, в котором оно представлено, действительно объединяет две проверки выражения,
Намерен ли автор проверять только бит 0 и намеревался использовать это выражение,
Или автор намеревался объединить значения для bit1-bitN и xor для bit0?
источник
Я добавляю новый ответ, потому что никто не объяснил, как получить ответ интуитивно.
Инверсия
+
есть-
.Инверсия
^
есть^
.Как вы решаете
0 != x - 1
дляx
? Вы+ 1
в обе стороны:0 + 1 != x - 1 + 1
→1 != x
.Как вы решаете
0 != x ^ 1
дляx
? Вы^ 1
в обе стороны:0 ^ 1 != x ^ 1 ^ 1
→1 != x
.источник
Я предполагаю, что в нем есть другие биты или значения битовых полей
x
, и это предназначено для проверки того, что установлен только младший бит. В контексте я бы предположил, что это значение по умолчанию, и, следовательно, кодирование этого и некоторого связанногоm
(возможно, более дорогостоящего для кодирования) может быть пропущено, поскольку оба они должны быть значением по умолчанию, инициализированным в конструкторе или аналогичным образом.Каким-то образом декодер должен сделать вывод, что эти значения отсутствуют. Если они находятся в конце некоторой структуры, это может быть передано через
length
значение, которое всегда присутствует.источник
XOR полезен в перечислении флага C #. Для удаления одиночного флага из значения перечисления необходимо использовать оператор xor (ссылка здесь )
Пример:
источник
Есть много хороших ответов, но мне нравится думать об этом проще.
Прежде всего. Оператор if является ложным, только если аргумент равен нулю. Это означает, что сравнивать не равное нулю бессмысленно.
Так что это оставляет нас с:
XOR с одним. То, что делает XOR, по сути, определяет биты, которые отличаются. Таким образом, если все биты одинаковы, он вернет 0. Поскольку 0 - ложь, единственный раз, когда он вернет ложь, - это если все биты одинаковы. Так что будет ложно, если аргументы одинаковы, истина, если они разные ... точно так же, как оператор not равно .
Если факт, единственное различие между ними состоит в том,
!=
что вернет 0 или 1, в то время как^
вернет любое число, но достоверность результата всегда будет одинаковой. Простой способ думать об этомПоследнее «упрощение» - это преобразование
0x1
в десятичное число, равное 1. Поэтому ваше утверждение эквивалентно:источник
^ - побитовый оператор XOR
Если х = 1
здесь 0 == (x ^ 0x1)
Если х = 0
здесь 0! = (x ^ 0x1)
Таблица истинности xor b:
Код просто означает
источник
Здесь можно использовать стандартную технику, состоящую в том, чтобы повторять идиому в том виде, в каком она появляется в окружающем контексте для ясности, а не запутывать ее, заменяя ее идиомой, которая арифметически проще, но не имеет смысла в контексте.
Окружающий код может часто ссылаться
(x ^ 1)
или тест может спрашивать: «Если бы бит 0 был наоборот, эта битовая маска была бы пустой?».Учитывая, что условие вызывает что-то для
encode()
редактирования, может случиться так, что в контексте состояние по умолчанию бита 0 было инвертировано другими факторами, и нам нужно только кодировать дополнительную информацию, если какой-либо из битов отклоняется от их значения по умолчанию (обычно все ноль) ).Если вы берете выражение из контекста и спрашиваете, что оно делает, вы упускаете из виду основное намерение. С таким же успехом вы можете посмотреть на вывод сборки из компилятора и увидеть, что он просто выполняет прямое сравнение на равенство с 1.
источник
Как я вижу ответы до сих пор пропустить простое правило для обработки
XOR
s. Не вдаваясь в подробности, что^
и что0x
означает (иif
, и!=
т. Д.), Выражение0 != (x^1)
можно переработать следующим образом, используя тот факт, что(a^a)==0
:источник