【问题标题】:What is the XOR operator evaluating when switching the int values of two variables? [duplicate]切换两个变量的 int 值时,XOR 运算符会评估什么? [复制]
【发布时间】:2012-09-13 13:24:33
【问题描述】:

可能重复:
How does XOR variable swapping work?


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

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

这是使用 exclusive-or 运算符(“XOR”),而不是布尔值(我假设它是 bitwise?)。最近学习了一些离散数学,我可以理解XOR运算符与真值表的用法:

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

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


无论如何,如果我将 x 和 y 设置为 int 值而不是布尔值,则操作不是很简单。因此,例如让x = 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.

【问题讨论】:

  • 欢迎回到汇编编程的旧时代(我认为这个技巧实际上是用来减少寄存器使用的)...出于好奇:您不打算在实际代码中的任何地方使用它吗? PS:恕我直言,这与 XORed 双向链表有些相关,也许你会觉得这很有趣:en.wikipedia.org/wiki/XOR_linked_list
  • 对汇编编程很感兴趣@Axel。这个 XOR 变量交换问题在许多博客中被提到是一个相关的面试问题,但在研究这个问题后,我发现它有点晦涩难懂而且不是很直观。我想我宁愿只使用第三个变量来做 2 个变量交换的事情,因为这更容易阅读。因此,尽管进一步深入兔子洞,我现在有兴趣学习如何将整数转换为位,以及可能有什么用途。这种二进制转换的相关性有多大?

标签: java boolean int xor


【解决方案1】:

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

【讨论】:

  • 是的,我知道这是一个有点简洁的答案,对此感到抱歉。
  • 哈没关系,感谢@Larry 的帮助!那么数字 3 究竟是如何并行分解为位的呢? 3 以比特为单位计算的值是多少?
  • 数字 3 是 0x0011。 (3 = 2^1+2^0)。数字 14 将是 0x1110 (14 = 8+4+2 = 2^3+2^2+2+1)。
【解决方案2】:

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

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

011
101
--- xor
110

110 是十进制的 6。

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

【讨论】:

  • 好的,谢谢@Sponiro,但是当x = 3y = 5 时,为什么x ^= y 中的x 等于6? x 和 y 变成什么位数才能计算为 6?
  • 我已经为你添加了一个例子。
  • 感谢@Sponiro 提供的清晰示例!我会研究这个“Horner 的方法”。
【解决方案3】:

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

3 = 011, 5 = 101

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

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

现在我们取第二个数字并与我们刚刚得到的差进行异或

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

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

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

【讨论】:

  • 感谢@Roger 的清晰解释和链接!
猜你喜欢
  • 2011-01-01
  • 2013-01-09
  • 2014-12-15
  • 2012-06-13
  • 1970-01-01
  • 2013-10-08
  • 2021-01-14
相关资源
最近更新 更多