Как работает побитовый оператор XOR ('^')?

Я немного смущен, когда вижу вывод следующего кода:

$x = "a";
$y = "b";
$x ^= $y;
$y ^= $x;
$x ^= $y;
echo $x; //Got b
echo $y; //Got a

Как здесь работает оператор ^?


person Young    schedule 20.04.2010    source источник
comment
Ответил в stackoverflow.com/questions/249423/   -  person Sebastian Paaske Tørholm    schedule 20.04.2010
comment
Вы спрашиваете как работает оператор или как работает своп?   -  person SLaks    schedule 20.04.2010
comment
@ Себастьян П, понял. Спасибо.   -  person Young    schedule 20.04.2010
comment
К вашему сведению: строки усекаются, если они содержат разное количество символов.   -  person Geo    schedule 09.01.2013


Ответы (6)


Это выглядит как замена значения с помощью XOR. Хотя я не уверен насчет строк в PHP (обычно вы используете его для целых чисел или чего-то еще). Таблицу истинности XOR вы можете найти здесь.

Что интересно в отношении XOR, так это то, что оно обратимо: A XOR B XOR B == A ... это не работает с AND или OR. Из-за этого его можно использовать, как в вашем примере, для замены двух значений:

$x ^= $y;
$y ^= $x;
$x ^= $y;

означает:

$x = $x ^ $y
$y = $y ^ ($x ^ $y)                // = $x
$x = ($x ^ $y) ^ ($y ^ ($x ^ $y))  // = $y
person tanascius    schedule 20.04.2010
comment
PHP динамически типизируется и ненавидит строки — он будет преобразовывать их в int или double всякий раз, когда представится такая возможность. - person Michael Borgwardt; 20.04.2010
comment
@Michael: Спасибо, что указали на это - я этого не знал и просто предположил, что что-то подобное происходит ^^ - person tanascius; 20.04.2010

^ — побитовый оператор «исключающее или». По-английски это читается как «либо, либо». Результат равен 1 тогда и только тогда, когда оба бита различаются:

1 ^ 0 = 1
1 ^ 1 = 0
0 ^ 0 = 0

Немного упрощая пример (и используя псевдокод):

$x = 0011 //binary
$y = 0010

$x = $x xor $y
//Result: x = 0001

//x = 0001
//y = 0010
$y = $y xor $x
//Result: y = 0011

//x = 0001
//y = 0011
$x = $x xor $y
//Result: x = 0010

Все, что сделал PHP, это обработал строки "a" и "b" как целочисленные эквиваленты.

person Yacoby    schedule 20.04.2010

В этом примере, когда вы используете символы ^, они преобразуются в целые числа. Так

"a" ^ "b"

такой же как:

ord("a") ^ ord ("b")

за одним исключением. В первом примере результат был приведен обратно к строке. Например:

"a" ^ "6" == "W"

потому что:

ord("a") ^ ord("6") == 87

и

chr(87) == "W"
person Denis Bazhenov    schedule 20.04.2010

Оператор Th ^ является побитовым оператором, что означает, что он работает с каждым битом своих операндов.

Он возвращает значение, в котором каждый бит равен 1, если два соответствующих бита в операндах не равны, и 0, если они равны.

Например:

   100110110
 ^ 010001100   
 = 110111010
person SLaks    schedule 20.04.2010
comment
В примере кода для вопроса операндами являются строки. Что на самом деле происходит? Например, используются ли значения ASCII? Что делать, если строки длиннее единицы? - person Peter Mortensen; 28.12.2015

Оператор ^ выполняет XOR над битовыми значениями каждой переменной. XOR делает следующее:

a   = 1100
b   = 1010
xor = 0110

x является результатом операции XOR. Если биты равны, результат равен 0, если они различны, результат равен 1.

В вашем примере ^= выполняет XOR и присваивание, и вы меняете местами биты между двумя переменными $x и $y.

Подробнее читайте здесь http://en.wikipedia.org/wiki/Xor_swap_algorithm

person Justin    schedule 20.04.2010

XOR либо эксклюзивный, либо основанный на логике и схемах. Это указывает, что, например, A ^= B, где A равно 0111, а B равно 0101, может быть либо 1, либо 0 в каждом соответствующем бите, но не в обоих. Следовательно

A = 0111
B = 0101
    _____
^=  0010 

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

Примечание. Таким образом, правила XOR позволяют вам взять результат A ^= B в приведенном выше примере и добавить к нему A, чтобы получить B, или добавить к нему B, чтобы получить A (ссылаясь на возможность обмена, упомянутую выше.

person ALJ    schedule 07.06.2014