XOR演算でswap


コードを書いていて, 値を入れ替えるときに,
C#は標準でswap関数は無いようなので,

if (from > to) // from > to だったら入れ替える
{
    var temp = from;
    from = to;
    to = temp;
}

と普通に書いていたら, 先輩が次のようにきれいにしてくれました!

static class math
{
    public static void swap<T>(ref T a, ref T b)
    {
        T temp = a;
        a = b;
        b = temp;
    }
}
***** func(~~~~)
{
    if (from > to) 
    {
        math.swap(ref to, ref from);
    }
    .....

なるほど, たしかに, swapはこれからも使う気がするから, こっちのほうがいいしコードもきれいになった!(((o(*゚▽゚*)o)))

そして, ついでに XOR で swap する方法も教えてくれました!

a と b を swap したいとき,

a^= b^= a^= b;

で交換できるらしいです(((o(*゚▽゚*)o)))

いったいこれは何をしているのでしょうか!

a ^ b

a XOR b

を表しているそうです.

それで,

a ^= b;

a = a ^ b;

なので,

a ^= b ^= a ^= b;

a ^= b ^= (a ^= b);

a ^= (b ^= (a ^= b));

なのです!

本当にこれでaとbが交換できるのでしょうか,
って, とても気になりました!

ためしてみます!
xor
画像: http://hyperphysics.phy-astr.gsu.edu/hbase/electronic/xor.html

a : 1011
b : 1110

のとき,

a : 1011
b : 1110
a^b : 0101
b^(a^b): 1011 ← a だ!!(((o(*゚▽゚*)o)))

おおお! たしかに b^(a^b) で a が取れています!


「XOR演算でswap」への6件のフィードバック

  1. この方法なんですが昔の時代のテクニックで今は使わないほうが良いようです。
    エフェクティブJavaに書いてありました。(>_<)

  2. まあ仕事では使わない方がいいけどちょまどさんはCodeGolferなのでビット演算も一通り覚えておいた方がいいのではないでしょうか

  3. 以前kazu_yamamotoさんあたりがツイートしてらっしゃった気がしますが、
    &a==&b のときにこれを使うとa,b両方の全ビットが0になるというバグがあるので使うべきではないです。

  4. kazu_yamamotoさんあたりが以前にツイートしてらっしゃった気がしますが、
    &a==&b の時にこれを使うとa,bの全ビットが0になるというバグがあるので使うべきではないです。

コメントを残す

メールアドレスが公開されることはありません。