1

重複の可能性:
XOR 変数のスワッピングはどのように機能しますか?


次のように、3 番目の変数を作成せず に、2 つの変数の値を切り替える解決策を見つけました。

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

両方の変数が等しい場合、式はfalse(x XOR y)と評価され、それ以外の場合はtrueと評価されます。しかし、値がブール値でない場合のWTFは?


とにかく、x と yをブール値ではなくint値に設定すると、操作は単純ではなくなります。したがって、たとえば let x = 3、 and y = 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

これが操作の仕組みです。まず、数値を 2 進数で書き込みます。

3 = 011、5 = 101

ここで、それらを xor すると、元の 2 つの数値の間でどのビットが異なるかを表す数値が得られます。

011 xor 101 => 110 これは 10 進数で 6 です。

次に、2 番目の数値と、取得した差で xor を取得します。

101 xor 110 => 011 (10 進数で 3) となり、これらの数値の差が得られ、元の最初の数値に戻ります。ここで、再びこの新しい数値を取得し、最初に取得した差と xor します。

011 xor 110 => 101 (10 進数の 5) となり、元の 2 番目の数値が返されました。

XOR Swap wikiでは、より明確な説明と、ほとんどの最新のアーキテクチャとコンパイラで一時変数を使用するよりも遅い理由を確認できます。

于 2012-09-21T06:33:12.570 に答える
3

XOR を数値型に適用すると、ビットごとの排他的論理和になります。したがって、元の真理値表を取得して、それを各ビットに並行して適用できます。それは何が起こっているのかを理解するのに役立つはずです。

于 2012-09-21T06:12:52.643 に答える
3

実際、あなたは自分で答えを出しました。int の xor はビット単位であると仮定しましたが、それは正しいです。数値をビット表現に変換してから、ビットごとに xor を適用します。

3 は 2 進数で 11 です。5 は 2 進数で 101 です

011
101
--- xor
110

110 は 10 進数で 6 です。

数値のバイナリ表現を計算する方法を知りたい場合は、ホーナーの方法を調べる必要があります。やり方はとても簡単です。

于 2012-09-21T06:17:38.240 に答える