17 ответов:
операция XOR (
x ^ 0x1) инвертирует бит 0. Таким образом, выражение эффективно означает: если бит 0 из x равен 0, или любой другой бит x равен 1, то выражение истинно.и наоборот выражение ложно, если x = = 1.
таким образом, тест такой же, как:
if (x != 1)и поэтому (возможно) излишне запутано.
^- это побитовое XOR операция0x1и1в hex-нотацииx ^ 0x1инвертирует последний битx(обратитесь к таблице истинности XOR в ссылке выше, если это вам не ясно).таким образом, условие
(0 != ( x ^ 0x1 ))будет true, еслиxбольше 1 или если последний битxравен 0. Остается только Х==1 в качестве значения, при котором условие будет ложным. Так это эквивалентноif (x != 1)P. S. адский способ реализовать такое простое условие, я мог бы добавить. Не делай этого. И если вы должны написать сложный код,оставить комментарий. Умоляю тебя.
Это может показаться слишком упрощенным объяснением, но если кто-то хотел бы пройти через это медленно это ниже:
^- это побитовое XOR оператор в C, C++ и C#.побитовое XOR принимает два битовых шаблона одинаковой длины и выполняет логической операцией "исключающее ИЛИ" над каждой парой соответствующих битов.
Exclusive или является логической операцией, которая выводит true всякий раз, когда оба входы отличаются (один верно, другое-ложь).
The таблица истинности на a xor b:
a b a xor b ---------------------------- 1 1 0 1 0 1 0 1 1 0 0 0Итак, давайте проиллюстрируем
0 == ( x ^ 0x1 )выражение на уровне двоичного кода:what? xxxxxxxx (8 bits) xor 00000001 (hex 0x1 or 0x01, decimal 1) gives 00000000 --------------------------- the only answer is 00000001так:
0 == ( x ^ 0x1 ) => x == 1 0 != ( x ^ 0x1 ) => x != 1
это эксклюзивный или (XOR) оператор. Чтобы понять, как это работает, вы можете запустить этот простой код
std::cout << "0x0 ^ 0x0 = " << ( 0x0 ^ 0x0 ) << std::endl; std::cout << "0x0 ^ 0x1 = " << ( 0x0 ^ 0x1 ) << std::endl; std::cout << "0x1 ^ 0x0 = " << ( 0x1 ^ 0x0 ) << std::endl; std::cout << "0x1 ^ 0x1 = " << ( 0x1 ^ 0x1 ) << std::endl;выход будет
0x0 ^ 0x0 = 0 0x0 ^ 0x1 = 1 0x1 ^ 0x0 = 1 0x1 ^ 0x1 = 0так это выражение
0 != ( x ^ 0x1 )будет равно true только тогда, когда x != 0x1.
он не изменяет x сам по себе. Он только проверяет, равен ли x 0 или 1. это rxpression может быть изменено на
if ( x != 0x1 )
он проверяет, что
xна самом деле не0x1...xoringxс0x1приведет к 0 только еслиxи0x1... это старый трюк в основном используется в языке ассемблера
The
^оператор побитовый xor. И0x1число1, записывается как шестнадцатеричная константа.и
x ^ 0x1вычисляет новое значение, которое совпадает сx, но с наименее значимым битом перевернутым.код не делает ничего, кроме сравнения x с 1, очень запутанным и неясным образом.
оператор xor (exclusive or) чаще всего используется для инвертирования одного или нескольких битов. Операция заключается в том, чтобы спросить, является ли один из битов одним, это приводит к следующей таблице истинности (A и B-входы, Y-выход):
A B Y 0 0 0 0 1 1 1 0 1 1 1 0теперь цель этого кода, кажется, чтобы проверить, если excatly последний бит равен 1, а остальные 0, это равно
if ( x != 1 ). Причина этого неясного метода может заключаться в том, что были использованы и, возможно, используются предыдущие методы обработки битов другие места в программе.
^- побитовоеxor operatorinc. В вашем случае x-это xor'ED с 1. напримерxимеет значение 10, то10d ^ 1d ===> 1010b ^ 0001b = 1011b, 1011b == 11dтак что условие становится истинным.
побитовый тест кажется преднамеренной путаницей, но если базовые данные являются корпоративными данными из системы мэйнфреймов IBM, это может быть просто то, что код был написан, чтобы отразить исходную документацию. Форматы данных IBM восходят к 1960-м годам и часто кодируют флаги как отдельные биты в слове для сохранения памяти. По мере изменения форматов в конце существующих записей добавлялись флаговые байты для обеспечения обратной совместимости. Документация для записи SMF, например, можно показать код языка ассемблера для проверки трех отдельных битов в трех разных словах в одной записи, чтобы решить, что данные являются входным файлом. Я знаю гораздо меньше о внутренних TCP/IP, но вы также можете найти там битовые флаги.
оператор ^ является побитовым-xor (см. &, | ). Результат для битовой пары,
0 ^ 0 == 0 0 ^ 1 == 1 1 ^ 0 == 1 1 ^ 1 == 0поэтому выражение,
( x ^ 0x1 )инвертирует / переворачивает 0-й бит x (оставляя другие биты без изменений).
рассмотрим, может ли x иметь значения помимо 0x0 и 0x1? Когда x-однобитовое поле, оно может иметь только значения 0x0 и 0x1, но когда x-int (char/short/long/etc), биты помимо bit0 могут влиять на результат выражения.
в выражение как дано позволяет битам рядом с bit0 влиять на результат,
if ( 0 != ( x ^ 0x1 ) )который имеет эквивалентную правдивость, как это (более простое) выражение,
if ( x ^ 0x1 )обратите внимание, что это выражение будет рассматривать только bit0,
if( 0x1 & ( x ^ 0x1 ) )таким образом, представленное выражение действительно объединяет две проверки выражений,
if( ( x & ~0x1 ) //look at all bits besides bit0 || ( x ^ 0x1 ) ) //combine with the xor expression for bit0автор намеревался только проверить bit0, и намеревался использовать это выражение,
if( 0x1 & ( x ^ 0x1 ) )или автор намеревался comingle значения для 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 (reference здесь)
пример:
[Flags] enum FlagTest { None 0x0, Test1 0x1, Test2 0x2, Test3 0x4} FlagTest test = FlagTest.Test2 | FlagTest.Test3; Console.WriteLine(test); //Out: FlagTest.Test2 | FlagTest.Test3 test = test ^ FlagTest.Test2; Console.WriteLine(test); //Out: FlagTest.Test3
есть много хороших ответов, но мне нравится думать об этом проще.
if ( 0 != ( x ^ 0x1 ) );прежде всего. Оператор if является ложным только в том случае, если аргумент равен нулю. Это означает, что сравнение не равно нулю бессмысленно.
if ( a != 0 ); // Same as if ( a );Итак, это оставляет нас с:
if ( x ^ 0x1 );XOR с одним. То, что делает XOR, по существу найти битов, которые отличаются. Итак, если все биты одинаковы, он вернет 0. Поскольку 0 равно false, то только раз он вернет false, если все биты одинаковы. Поэтому он будет ложным, если аргументы одинаковы, истинным, если они разные...так же, как не равно оператора.
if ( x != 0x1 );если факт, то единственная разница между ними заключается в том, что
!=возвращает 0 или 1, в то время как^вернет любое число, но truthyness результат всегда будет один и тот же. Простой способ думать об этом.(b != c) === !!(b ^ c) // for all b and cв окончательное "Упрощение" - это преобразование
0x1к десятичной дроби, которая равна 1. Поэтому ваше утверждение эквивалентно:if ( x != 1 )
^ является побитовое XOR оператор
Если x = 1
00000001 (x) (decimal 1) 00000001 (0x1) (decimal 1) XOR 00000000 (0x0) (decimal 0)здесь 0 = = (x ^ 0x1)
Если x = 0
00000000 (x) (decimal 0) 00000001 (0x1) (decimal 1) XOR 00000001 (0x1) (decimal 0)здесь 0 != (x ^ 0x1 )
таблица истинности xor b:
a b a xor b ---------------------------- 1 1 0 1 0 1 0 1 1 0 0 0код просто означает
как я вижу ответы до сих пор пропустить простое правило для обработки
XORs. Не вдаваясь в подробности, что^и0xзначит (иifи!=etc), выражение0 != (x^1)можно переработать следующим образом, используя тот факт, что(a^a)==0:0 != (x^1) <=> [xor left and right side by 1] (0^1) != (x^1^1) <=> 1 != x
стандартная техника, которая может здесь используется, чтобы повторить идиому, как она появляется в окружающем контексте для ясности, а не запутать ее, заменив ее идиомой, которая арифметически проще, но контекстуально бессмысленна.
окружающий код может часто ссылаться на
(x ^ 1), или тест может спросить: "если бы бит 0 был наоборот, эта битовая маска была бы пустой?".учитывая, что условие вызывает что-то должно быть
encode()ed, возможно, что в контексте состояние по умолчанию бита 0 было инвертировано другими факторами, и нам нужно только кодировать дополнительную информацию, если какой-либо из битов отклоняется от их значения по умолчанию (обычно все-ноль).
Comments