はじめに
XOR(排他的論理和)は、コンピュータプログラミングにおける基本的なビット演算の一つです。単純な演算でありながら、ちょっと変わった使い方もできます。
想定する読者
- プログラミングの基礎を理解している方
- ビット演算について学びたい方
- XORの使われているコードの内容を理解したい方
XORの基本
定義と性質
XOR(eXclusive OR)は、2つの入力のうち「どちらか一方だけが真」の場合に真となる論理演算です。
真理値表:
a b | a XOR b
-----------------
0 0 | 0
0 1 | 1
1 0 | 1
1 1 | 0
XORの重要な性質:
- 交換法則:
a XOR b = b XOR a
- 結合法則:
(a XOR b) XOR c = a XOR (b XOR c)
- 自己反転性:
a XOR a = 0
- 単位元:
a XOR 0 = a
応用例
1. 値の交換
XORを使って2つの変数の値を交換することができます:
void swap(int *a, int *b) {
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
2. 特定のビットの反転
XORは指定したビットを反転させるのに適しています:
unsigned int flip_bit(unsigned int x, unsigned int position) {
return x ^ (1U << position);
}
3. データの比較
2つの値が異なるかどうかの比較は、XORを使って次のように書くこともできます:
bool values_differ(int a, int b) {
return (a ^ b) != 0;
}
4. 特定のビットパターンの検出
XORを使用して、特定のビットパターンを効率的に検出できます:
bool has_zero_byte(unsigned int v) {
return ((v - 0x01010101UL) & ~v & 0x80808080UL) != 0;
}
パフォーマンスの考慮事項
- XOR演算は通常、1サイクルで実行できる高速な演算です
- ビットレベルの操作が必要な場合に特に有用です
- ただし、可読性とメンテナンス性も考慮する必要があります
まとめ
XORは以下のような場面で特に有用です:
- 暗号化や特殊なビット操作が必要な場合
- ハードウェアレベルの最適化が必要な場合
- 特定のビットパターンの検出や操作
ただし、単純な処理の場合は、より直感的で可読性の高い標準的な方法を選択することが推奨されます。
注意事項
Update: コメントでいただいたフィードバックを反映しました
各応用例における実装上の注意点:
値の交換について
- XORを使う方法は、一時変数を使う方法と比べてレジスタの使用数は減りますが、実際のメモリ使用量は変わりません
- 一時変数を使う方法のほうが、同一アドレスのチェックも不要で単純な実装になります
データの比較について
- XORを使う比較は、通常の比較演算子(!=)を使用した場合と同じコンパイル結果になります
- 可読性の観点から通常の比較演算子を使用することをおすすめします