布林算式(Boolean Expressions)

元素對元素布林算式(Element-by-element Boolean Operators)

元素對元素布林算式(element-by-element boolean operators)是指使用元素對元素布林運算子(element-by-element boolean operators)與小括號將比較算式連接起來的算式,布林運算子包含:and(&)、or(|) 與 not(!),而小括號是用於控制計算的優先順序。布林算式的運算結果是由其中的比較算式的結果再經由布林運算子運算而得到,若結果為 true 則傳回 1,否則傳回 0

在任何比較算式可以使用的地方也都可以使用元素對元素布林算式,例如 ifwhile 判斷式中都可以使用元素對元素布林算式。

ifwhile 等判斷式中使用矩陣時,若矩陣中所有的元素皆不為 0,則傳回 true,否則傳回 false

若將元素對元素布林算式用於數值運算或儲存至變數中,當其運算結果為 true 時,其傳回值為 1,而結果為 false 時,其傳回值為 0。例如:

a = 1;
b = 2;
c = (a < 2) & (b > 1)

輸出為

c =  1

以下是 Octave 中的元素對元素布林運算子:

  • boolean1 & boolean2:將 boolean1boolean2 中對應的元素做 AND 運算。
  • boolean1 | boolean2:將 boolean1boolean2 中對應的元素做 OR 運算。
  • ! boolean:對 boolean 中每個元素做 NOT 運算。
  • ~ boolean:與 ! boolean 相同。

若輸入的運算元為矩陣為矩陣,則會對每個元素做運算,例如:

[1, 0; 0, 1] & [1, 0; 2, 3]

輸出為

ans =

   1   0
   0   1

對於二元的元素對元素布林運算子(即 &|),若兩個運算元(也就是上面的 boolean1boolean2)皆為矩陣,則兩個矩陣的大小必須相同;若一個運算元為純量,而另一個是矩陣,則會以純量對每個矩陣中的元素做運算。

由二元的元素對元素布林運算子所連接的算式(即上面的 boolean1boolean2)會在計算結果之前先被執行,這在元素對元素布林算式含有邊際效應時會產生差異,例如:

a & b++

即使 a 的值為 0b 依然會遞增。

短路布林運算子(Short-circuit Boolean Operators)

Octave 所提供的元素對元素布林運算子配合其自動轉換為數值的特性,對於大部分的情況而言已經足夠了,但有時候使用者會希望當運算結果已經確定時,可以跳過不需要的運算,短路布林運算子(Short-circuit Boolean Operators)就是為了這個而設計的:

  • boolean1 && boolean2boolean1 算式會以 all (boolean1(:)) 的方式檢查其是否為 true,若為 false 則不執行 boolean2,整個算式會傳回 0;若 boolean1true,則 boolean2 算式會以 all (boolean2(:)) 的方式檢查其是否為 true,若為 true 則整個算式會傳回 1,否則傳回 0
  • boolean1 || boolean2boolean1 算式會以 all (boolean1(:)) 的方式檢查其是否為 true,若為 true 則不執行 boolean2,整個算式會傳回 1;若 boolean1false,則 boolean2 算式會以 all (boolean2(:)) 的方式檢查其是否為 true,若為 true 則整個算式會傳回 1,否則傳回 0
boolean1 為空矩陣時,使用 all (boolean1(:)) 時有一個例外,即使 all ([])true,但 [] && true 依然為 false

短路布林運算子所連接的算式有可能不會被直行,例如:

a && b++

只有當 a 不是 0 時,b 才會遞增。

善用短路布林運算子的特性可以讓程式碼更簡潔,例如:

function f (a, b, c)
  if (nargin > 2)
    if (ischar (c))
      ...

可以使用短路布林運算子改寫成:

function f (a, b, c)
  if (nargin > 2 && ischar (c))
    ...

若是寫成

function f (a, b, c)
  if (nargin > 2 & ischar (c))
    ...

則在 f() 函數只有輸入一個或兩個參數時,會產生錯誤,因為 & 運算子會先執行其兩邊的運算元。