Простой Java-код возвращает неожиданный результат - PullRequest
1 голос
/ 14 ноября 2011

Следующий простой Java-код возвращает неожиданный вывод.Давайте посмотрим на это.

package interchange;

final public class Main
{
    public static void main(String[] args)
    {
        int x = 15;
        int y = 20;

        x^=y^=x^=y;
        System.out.println("x = " + x + "; y = " + y);
    }
}

Приведенный выше код отображает на консоли следующий вывод:

x = 0; y = 15

Как?

Ответы [ 5 ]

6 голосов
/ 14 ноября 2011

В соответствии с приоритетом оператора его можно переписать так:

x^=y; // 15 ^ 20 = 27, x = 27
y^=27; // 20 ^ 27 = 15, y = 15
x^=15; // 15 ^ 15 = 0, x = 0
3 голосов
/ 14 ноября 2011

Вы в основном делаете x XOR x (потому что вы применяете операцию xor дважды с одним и тем же операндом (y)), и это приводит к 0.

Давайте оценим ваше выражение шаг за шагом, в вашем случае мы имеемчтобы сделать это справа налево, чтобы следовать приоритету:

     x^=y^=x^=y; 
<=>  y^x^y^x 
<=> (y^y) ^ (x^x) 
<=> (0) ^ (0) 
<=>  0
1 голос
/ 14 ноября 2011

У меня нет фактического ответа, но я не думаю, что проблема в приоритете. Добавив скобки для уточнения, происходит то же самое:

//   3   2   1
   x^=(y^=(x^=y));

То, что я ожидал бы , ожидал , что-то эквивалентное:

x^=y; //1: xor x with y, update x, return the new x;
y^=x; //2: xor y with (result of 1), update y, return the new y;
x^=y; //3: xor x with (result of 2), update x, return the new x;

На самом деле, я думаю, что используются начальные значения, что фактически означает:

x0 = x;
y0 = y;
x = x0^y0^x0^y0; //0
y = y0^x0^y0;    //15

Проблема в том, что я не уверен, где в спецификации языка я могу найти это. Самое близкое, к чему я пришел, было:

15.7.2 Оценка операндов перед операцией

Язык программирования Java также гарантирует, что каждый операнд оператора (кроме условные операторы &&, || и? :), кажется, полностью оценен перед выполнением любой части самой операции.

1 голос
/ 14 ноября 2011

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

x = 1001
y = 1110

x ^= y => 0111
y ^= x ^= y => 1001
x ^= y ^= x ^= y = 0000

Обратите внимание:

x <=> y ^= x ^= y

Это означает, что вы в конечном итоге выполняете:

x ^= x

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

Для полноты изложения приведем проработку с использованием предоставленных значений для x и y:

x = 0000 1111
y = 0001 1011

x ^= y = 0001 0100
y ^= x ^= y => 0000 1111
x ^= y ^= x ^= y => 0000 0000
1 голос
/ 14 ноября 2011

XOR работает по правилам, что 1 XOR 1 = 0 и 1 XOR 0 = 1 и 0 XOR 0 = 0

В случае, если вы думали, что ^ = power.

15 в двоичном виде= 01111 20 в двоичном виде = 10100

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