XOR 的運算性質及應用

xr2439
4 min readSep 17, 2020

--

摘要

  • 實質運算意義上為一種特別的加法運算:
    A XOR B = (A + B) mod 2
  • A XOR B ,若 B = 1…1,則可視為針對 A 的各個 bits 做 toggle
  • 應用:
    (1) 英文字母大小寫轉換
    (2) 不使用暫存變數進行兩個變數的 swap
    (3) Leetcode — Problem 136. Single Number 的解法

介紹

XOR,其全名為 exclusive or ~

下方是 XOR 的真值表

從中不難理解為何叫做 exclusive or:當遇到兩個 Input 不同時,其結果為 1 ;其餘情況都為 0 。

這樣的運算性質在程式上有些很特別的用法,如:

(1) 英文字母大小寫轉換

Source: Re: [問卦] C程式大神們請進

英文字母的大小寫其 ASCII Code 的數值差了 32 (e.g. ‘A’ + 32 = ‘a’, ‘a’ - 32 = ‘A’),而 32 表示成二進位為 0010 0000。

只考慮單個位元的話,根據 XOR 的運算性質,一個位元 (記為 x) 與 1 做 XOR 的結果為對該 Bit 做 Toggle,因此大小寫的轉換可以透過這樣的方式達成

(2) 不用任何暫存變數,來交換 (Swap) 兩個變數的值

透過觀察 XOR 真值表的運算結果,考慮單一個 Bit,發現 XOR 結果為其差值 (不考慮正負號的話)。

故第一行 x ^= y可解釋成 x 為 x 與 y的差值,第二行 y ^= x 可解釋為 y 與 “x 與 y的差值” 的差值,也就是 8 ^ (5 ^ 8)

由於 XOR 有交換律、結合律的性質,故 8 ^ (5 ^ 8) = 8 ^ (8 ^ 5) = (8 ^ 8) ^ 5 = 0 ^ 5 = 5

所以這時候變數 y 已經變成 x 的值了,後面以此類推,可以讓變數 x 變成原本 y 的值。

(3) 給定一個 Array,在這些 Array 中的每個數字都會出現兩次,除了某一個數字只出現一次,請找出該數字。

Source: Leetcode — Problem 136. Single Number

同上,XOR 可解釋成計算兩個數的差值,假設 Array 中的數字依序是 A1, A2, A2, A3, A1,那麼 A1 ^ A2 ^ A2 ^ A3 ^ A1 根據交換律及結合律重新排列一下可以得到 A1 ^ A1 ^ A2 ^ A2 ^ A3 = (A1 ^ A1) ^ (A2 ^ A2) ^ A3 = 0 ^ 0 ^ A3 = A3 ,故可以得到唯一的數字。

XOR 運算的意義

若能針對 XOR 運算有以上的解釋 (Bit 的 Toggle & 差值的概念),而非拘泥於真值表的計算結果,就會發現 XOR 並非這麼抽象。

不過更進一步分析,對數字敏感的人其實會發現,XOR 運算子是一種特殊的加法:

A XOR B = (A + B) mod 2

也就是說 A XOR B 的計算結果是 A + B 後,除以 2 得到的餘數

我們從這個角度出發來看待 XOR 運算,重新考慮上面的例子:

(1) 英文字母大小寫轉換
假設 ch 的 Binary Representation 為 abcdefgh,為了方便,我們記為 (a, b, c, d, e, f, g, h)。

ch ^ 32 =
(a, b, c, d, e, f, g, h) + (0, 0, 1, 0, 0, 0, 0, 0) mod 2 =
(a, b, (c + 1) mod 2, d, e, f, g, h)

因此整個計算結果,只會針對 c 這個位元會產生變化,若 c = 0,則結果為 (0 + 1) mod 2 = 1;反之,若 c = 1,則結果為 (1 + 1) mod 2 = 0。

透過這方式可以很簡單的理解為什麼 XOR 會有 Toggle 特定 Bit 的特性。

(2) 不用任何暫存變數,來交換 (Swap) 兩個變數的值

同理,假設 x = (a, b, c, d, e, f, g, h) 及 y = (i, j, k, l, m, n, o, p) 則
x ^= y, y ^= x 可視為
y = y ^ (x ^ y) =
(y + x + y) mod 2 =
(2i + a, 2j + b, 2k + c, 2l + d, 2m + e, 2n + f, 2o + g, 2p + h) mod 2 =
(a, b, c, d, e, f, g, h) = x 原本的值

第三個例子也是同樣的原理可以推得~

--

--

xr2439
xr2439

Written by xr2439

Share Linux & Math Stuff

No responses yet