Что означает (x ^ 0x1)!= 0?

Я наткнулся на следующий фрагмент кода

if( 0 != ( x ^ 0x1 ) )
     encode( x, m );

Что означает x ^ 0x1? Это какой-то стандартный метод?

Ответ 1

Операция XOR (x ^ 0x1) инвертирует бит 0. Таким образом, выражение эффективно означает: если бит 0 из x равен 0 или любой другой бит x равен 1, то выражение истинно.

И наоборот, выражение false, если x == 1.

Итак, тест такой же, как:

if (x != 1)

и, следовательно, (возможно) излишне запутывается.

Ответ 2

  • ^ - побитовая операция XOR
  • 0x1 1 в шестнадцатеричной нотации
  • x ^ 0x1 инвертирует последний бит x (обратитесь к таблице истинности XOR в ссылке выше, если это вам не понятно).

Итак, условие (0 != ( x ^ 0x1 )) будет истинным, если x больше 1 или если последний бит x равен 0. Это оставляет только x == 1 как значение, при котором условие будет ложным, Таким образом, это эквивалентно

if (x != 1)

Р. С. Ад, способ реализовать такое простое условие, я мог бы добавить. Не делай этого. И если вы должны написать сложный код, оставить комментарий. Прошу вас.

Ответ 3

Это может показаться упрощенным объяснением, но если кто-то захочет пройти его медленно, он будет ниже:

^ является побитовым XOR в c, С++ и С#.

Побитовое XOR принимает два битовых шаблона равной длины и выполняет логическое исключающее ИЛИ для каждой пары соответствующих битов.

Эксклюзивная ИЛИ - логическая операция, которая выводит значение true, когда оба входы различаются (одно верно, другое - false).

таблица истинности 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

Ответ 4

Это эксклюзивный оператор OR (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. это выражение может быть изменено на

if ( x != 0x1 )

Ответ 5

Он проверяет, что x на самом деле не 0x1... xor ing x с 0x1 приведет к 0, только если x is 0x1... это старый трюк в основном используется на языке ассемблера

Ответ 6

Оператор ^ побитовый xor. А 0x1 - это число 1, записанное как шестнадцатеричная константа.

Итак, x ^ 0x1 оценивает новое значение, которое совпадает с x, но с наименее значимым битом.

Код не более чем сравнивает x с 1, очень запутанным и неясным образом.

Ответ 7

Оператор xor (exclusive или) чаще всего используется для инвертирования одного или нескольких битов. Операция заключается в том, чтобы спросить, действительно ли один из битов один, это приводит к следующей таблице истинности (А и В - входы, вывод Y):

A    B    Y
0    0    0
0    1    1
1    0    1
1    1    0

Теперь цель этого кода состоит в том, чтобы проверить, действительно ли последний бит равен 1, а остальные равны 0, это равно if ( x != 1 ). Причина этого неясного метода может заключаться в том, что использовались предшествующие методы манипулирования бит и, возможно, используются другие места в программе.

Ответ 8

^ побитно xor operator в c. В вашем случае x xor'ed с 1. например x имеет значение 10, затем 10d ^ 1d ===> 1010b ^ 0001b = 1011b, 1011b == 11d, поэтому условие становится истинным.

Ответ 9

Побитовое тестирование кажется преднамеренным запутыванием, но если основными данными являются корпоративные данные из системы мейнфреймов IBM, просто может быть, что код был написан для отражения исходной документации. Форматы данных IBM возвращаются к 1960 году и часто кодируют флаги как отдельные биты в слове для сохранения хранилища. По мере того, как форматы были изменены, в конце существующих записей добавлялись флаги, чтобы поддерживать обратную совместимость. Документация для записи SMF, например, может показать код языка ассемблера для проверки трех отдельных битов в трех разных словах в одной записи, чтобы решить, что данные являются входными файлами. Я знаю гораздо меньше о внутренних компонентах TCP/IP, но вы также можете найти там битовые флаги.

Ответ 10

Я бы предположил, что в x есть другие биты или значения битового поля, и это предназначено для проверки того, что установлен только бит младшего разряда. В контексте я бы предположил, что это значение по умолчанию, и поэтому кодирование этого и некоторых связанных m (возможно, более дорогостоящих для кодирования) может быть пропущено, поскольку они должны быть значением по умолчанию, инициализированным в конструкторе или похожие.

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

Ответ 11

Оператор ^ является побитовым 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 )

Обратите внимание, что это выражение будет проверять только бит0,

if( 0x1 & ( x ^ 0x1 ) )

Таким образом, представленное выражение действительно объединяет две проверки выражений,

if( ( x & ~0x1 )  //look at all bits besides bit0
||  ( x ^ 0x1 ) ) //combine with the xor expression for bit0

Намерен ли автор проверить только бит0 и использовать это выражение,

if( 0x1 & ( x ^ 0x1 ) )

Или автор намеревался объединить значения для бит1-битN и xor бит0?

Ответ 12

Я добавляю новый ответ, потому что никто не объяснил, как получить ответ интуитивно.

Обратный к + равен -.
Обратным к ^ является ^.

Как вы решаете 0 != x - 1 для x? Вы + 1 с обеих сторон: 0 + 1 != x - 1 + 11 != x.
Как вы решаете 0 != x ^ 1 для x? Вы ^ 1 с обеих сторон: 0 ^ 1 != x ^ 1 ^ 11 != x.

Ответ 13

XOR полезен в перечислении флагов С#. Чтобы удалить один флаг из значения перечисления, необходимо использовать оператор xor (ссылка здесь)

Пример:

[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

Ответ 14

Есть много хороших ответов, но мне нравится думать об этом более простым способом.

if ( 0 != ( x ^ 0x1 ) );

Прежде всего. Оператор if является только ложным, если аргумент равен нулю. Это означает, что сравнение, не равное нулю, бессмысленно.

if ( a != 0 );
// Same as
if ( a );

Итак, это оставляет нас:

if ( x ^ 0x1 );

XOR с одним. То, что делает XOR, по существу, определяет биты, которые отличаются друг от друга. Итак, если все биты совпадают, он вернет 0. Поскольку 0 является ложным, единственный раз, когда он вернет false, будет, если все биты совпадают. Таким образом, он будет ложным, если аргументы будут одинаковыми, истинными, если они будут разными... точно так же, как не равно оператору.

if ( x != 0x1 );

Если факт, единственное различие между ними состоит в том, что != вернет 0 или 1, а ^ вернет любое число, но истинность результата всегда будет одинаковой. Легкий способ подумать об этом.

(b != c) === !!(b ^ c) // for all b and c

Окончательное "упрощение" преобразует 0x1 в десятичный, что равно 1. Поэтому ваше утверждение эквивалентно:

if ( x != 1 )

Ответ 15

^ является побитовым 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

Код просто означает

Ответ 16

Как я вижу, ответы до сих пор пропускают простое правило для обработки XOR s. Не вдаваясь в подробности, что означают ^ и 0xif и != и т.д.), Выражение 0 != (x^1) можно переработать следующим образом, используя тот факт, что (a^a)==0:

0 != (x^1) <=> [xor left and right side by 1]
(0^1) != (x^1^1) <=>
1 != x

Ответ 17

Стандартная методика, которая может быть использована здесь, заключается в том, чтобы повторить идиому, как она появляется в окружающем контексте, для ясности, а не для обфускации ее, заменив ее идиомой, которая является арифметически более простой, но контекстуально бессмысленной.

Окружающий код может часто ссылаться на (x ^ 1), или тест может запрашивать "если бит 0 был наоборот, будет ли эта битовая маска пуста?".

Учитывая, что условие вызывает что-то encode() ed, может быть, что в контексте состояние по умолчанию бит 0 было инвертировано другими факторами, и нам нужно только кодировать дополнительную информацию, если какой-либо из бит отклоняется от их default (обычно all-zero).

Если вы вынесете выражение из контекста и спросите, что он делает, вы упускаете из виду основное намерение. Вы можете просто посмотреть на сборку из компилятора и увидеть, что он просто сравнивает прямые сравнения с 1.