1

可能重复:
异或变量交换如何工作?


我找到了一个在不创建第三个变量的情况下 切换两个变量的值的解决方案,如下:

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

这是以布尔以外的方式使用异运算符(“XOR”)(我假设它是按位的?)。最近学习了一些离散数学,我可以理解 XOR 运算符与真值表的用法:

.......................
    x  y  (x XOR y)
.......................
    T  T      F
    T  F      T
    F  T      T
    F  F      F

两个变量相等时,表达式的(x XOR y)计算结果为,否则为真。但是当值不是布尔值时WTF?


无论如何,如果我将 x 和 y 设置为int值而不是布尔值,则操作不是很简单。因此,例如 letx = 3y = 5

public class SwitchValues
{
    // instance methods
    public void SwitchBoolean(boolean x, boolean y)
    {
        System.out.println("The variable \"x\" is initially: " + x + ".\n" +
            "The variable \"y\" is initially: " + y + ".");
        x ^= y;
        System.out.println("x ^= y is equal to: " + x + ".");
        y ^= x;
        System.out.println("y ^= x is equal to: " + y + ".");
        x ^= y;
        System.out.println("x ^= y is now equal to: " + x + ".");

        System.out.println("The variable \"x\" is now: " + x + ".\n" +
            "The variable \"y\" is now: " + y + ".\n");
    } // end of SwitchBoolean

    public void SwitchInts(int x, int y)
    {
        System.out.println("The variable \"x\" is initially: " + x + ".\n" +
            "The variable \"y\" is initially: " + y + ".");
        x ^= y;
        System.out.println("x ^= y is equal to: " + x + ".");
        y ^= x;
        System.out.println("y ^= x is equal to: " + y + ".");
        x ^= y;
        System.out.println("x ^= y is now equal to: " + x + ".");

        System.out.println("The variable \"x\" is now: " + x + ".\n" +
            "The variable \"y\" is now: " + y + ".\n");
    } // end of SwitchInts

    // main method
    public static void main(String[] args)
    {
        SwitchValues obj = new SwitchValues();

        obj.SwitchBoolean(true, false);
        obj.SwitchInts(3, 5);

    } // end of main method
} // end of class SwitchValues


...并且为 int 值打印的结果如下:

The variable "x" is initially: 3.
The variable "y" is initially: 5.
x ^= y is equal to: 6.
y ^= x is equal to: 3.
x ^= y is now equal to: 5.
The variable "x" is now: 5.
The variable "y" is now: 3.
4

3 回答 3

4

这就是操作的工作方式。首先,我们将用二进制写入您的数字:

3 = 011, 5 = 101

现在,当我们对它们进行异或运算时,我们得到一个数字,它表示两个原始数字之间哪些位不同。

011 xor 101 => 110,即十进制的 6。

现在我们取第二个数字和我们刚刚得到的差值异或

101 xor 110 => 011(十进制为 3),我们得到这些数字之间的差异,我们回到原来的第一个数字。现在我们再次取这个新数字并与我们最初得到的差异进行异或

011 xor 110 => 101(十进制5),我们得到了原来的第二个数字。

XOR Swap wiki上,您可以看到更清晰的描述,并推断为什么这比在大多数现代架构和编译器上使用临时变量要慢。

于 2012-09-21T06:33:12.570 回答
3

应用于数值类型时的 XOR 是逐位异或。因此,您可以获取原始真值表并将其并行应用于每个位。这应该有助于了解正在发生的事情。

于 2012-09-21T06:12:52.643 回答
3

其实你自己给了答案。您假设 int 上的 xor 是按位的,那是正确的。将数字转换为位表示,然后逐位应用异或。

3 是二进制的 11。5 是二进制的 101

011
101
--- xor
110

110 是十进制的 6。

如果你想知道如何计算一个数字的二进制表示,你应该查看霍纳的方法。它很容易做到。

于 2012-09-21T06:17:38.240 回答