简单的Java代码会返回一些意外的结果

时间:2011-11-14 19:00:00

标签: java bit-manipulation

以下最简单的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 个答案:

答案 0 :(得分:6)

根据运算符优先级,可以像这样重写

x^=y; // 15 ^ 20 = 27, x = 27
y^=27; // 20 ^ 27 = 15, y = 15
x^=15; // 15 ^ 15 = 0, x = 0

答案 1 :(得分:3)

您基本上执行x XOR x(因为您使用相同的操作数(y)应用xor操作两次),结果为0。

让我们一步一步评估您的表达,在您的情况下,我们必须从右到左执行以遵循优先顺序:

     x^=y^=x^=y; 
<=>  y^x^y^x 
<=> (y^y) ^ (x^x) 
<=> (0) ^ (0) 
<=>  0

答案 2 :(得分:1)

XOR按1 XOR 1 = 0和1 XOR 0 = 1且0 XOR 0 = 0

的规则运行

如果你认为^ =是权力。

15 in binary = 01111 二进制20 = 10100

答案 3 :(得分:1)

对于在其一个或另一个操作数中出现的每个位,XOR返回true,但不是两者都返回。通过一个更简单的例子可能有所帮助:

x = 1001
y = 1110

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

请注意:

x <=> y ^= x ^= y

这意味着你最终会表现出来:

x ^= x

...必须为0,基于XOR的定义。

为了完整起见,这是使用xy提供的值的工作:

x = 0000 1111
y = 0001 1011

x ^= y = 0001 0100
y ^= x ^= y => 0000 1111
x ^= y ^= x ^= y => 0000 0000

答案 4 :(得分:1)

我没有实际答案,但我认为优先权不是问题。添加括号以澄清,同样的事情发生:

//   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 Evaluate Operands before Operation

     

Java编程语言也保证了运算符的每个操作数(除了   条件运算符&amp;&amp;,||和? :)似乎是完全评估   在执行操作本身的任何部分之前。