位元操作(Bit Manipulations)

Octave 提供了許多操控位元的函數,最基本的就是取得與設定數值中的指定位元:

bitset (a, n)
bitset (a, n, v)

bitset() 會設定 a 中第 n 個位元值為 v,參數 n 為大於 0 的整數;參數 v10,若是不指定則預設為 1。例如:

a = 10
dec2bin(a)
b = bitset(a, 1)
dec2bin(b)
X = bitget (a, n)

bitget(a, n) 傳回 a 中第 n 個位元值,例如:

bitget(4, 3)

參數 n 亦可以向量或範圍表示法指定:

bitget(4, 1:4)
bitget(4, 4:-1:1)
bitget(4, [1, 3])

在 Octave 中除了 bitcmp() 函數之外,所有的位元操作函數都可以接受純量或陣列,當一個以上的參數是陣列時,這些陣列必須要有相同的大小,而 Octave 會針對陣列中每個元素個別進行位元運算,若只有一個參數是陣列而其餘的參數是純量時,純量的參數會自動重複以配合陣列的元素進行運算,例如:

bitget(100, 8:-1:1)

第一個參數是純量,第二個參數是 18 陣列,因此 Octave 會將第一個參數重複 8 次,就像這樣:

bitget(100 * ones(1, 8), 8:-1:1)

這兩個寫法是一樣的。

Octave 的位元運算都是針對整數的位元作運算,即便傳入的數值是浮點數,Octave 也會自動轉為整數,例如:傳入浮點數 10 會被視為整數,因此其各個位元的值為 [1, 0, 1, 0],而不是表示浮點數的位元值。

在位元運算中常常會需要查詢可以被浮點數表示的最大的整數,尤其是在建立遮罩(mask)的時候,這時可以使用 bitmax() 函數:

bitmax ()

傳回可以被浮點數表示的最大整數,在 IEEE-754 的系統中是 2^53-1。這個函數可以看成是 intmax() 函數的浮點數版本。

Octave 也支援 andorxor 位元運算:

bitand (x, y)

bitand(x, y) 傳回 xy 的位元 AND 運算,xy 為大於或等於 0 且小於或等於 bitmax 的無號整數。

bitor (x, y)

bitor(x, y) 傳回 xy 的位元 OR 運算,xy 為大於或等於 0 且小於或等於 bitmax 的無號整數。

bitxor (x, y)

bitxor(x, y) 傳回 xy 的位元 XOR 運算,xy 為大於或等於 0 且小於或等於 bitmax 的無號整數。

bitcmp (a, k)

bitcmp(a, k) 傳回 a 的位元 NOT 運算結果,也就是 a 的補數(complement),參數 k 是指定傳回運算結果的位元數,若不指定則預設是 log(bitmax) + 1,例如:

bitcmp(7, 4)
dec2bin(11)
dec2bin(bitcmp(11, 6))
bitshift (a, k)
bitshift (a, k, n)

bitshift(a, k, n) 傳回 a 位元 shift 的結果。參數 k 是指定 shift 的距離,正整數代表向左,負整數代表向右;參數 n 是指定傳回運算結果的位元數,若不指定則預設是 log(bitmax) + 1,例如:

bitshift (eye (3), 1)
bitshift (10, [-2, -1, 0, 1, 2])

經過位元 shift 運算超出左右兩邊邊界的位元將會遺失。

Octave 的位元 shift 運算會將負整數的負號保留,例如:

bitshift (-10, -1)
bitshift (int8 (-1), -1)

bitshift (int8 (-1), -1) 的運算結果是 -1,原因是在於 int8 類型的 -1 ,其二進位表示為 [1, 1, 1, 1, 1, 1, 1, 1],經過位元 shift 運算之後,還是維持一樣的值。