Ch18. 位元運算子與運算子函式
18.1 位元運算子 Swift的位元運算子(bitwise operator)計有&(且)、|(或)、^(互斥 或)、~(反)、<<(左移),及>>(右移)。 位元運算子比關係運算子來得低,而比邏輯運算子來得高,但 ~、<<、>>是例外。 位元運算子的結合性也是由左至右。 其中 & 運算子,表示兩個位元皆為1時,結果才為1,否則為0。
位元運算子 & 的真值表 位元1 位元2 位元1 & 位元2 1
位元運算子 | 的真值表 位元1 位元2 位元1 | 位元2 1
位元運算子 ^ 的真值表 位元1 位元2 位元1 ^ 位元2 1 位元運算子 ~ 的真值表 位元 ~ 位元 1
18.1.1 用來判斷與設定位元的狀態 位元 & 與 | 運算子常用來處理遮罩(mask)的問題。 18.1.1 用來判斷與設定位元的狀態 位元 & 與 | 運算子常用來處理遮罩(mask)的問題。 常用來判斷哪些位元是1,而 | 常用來將某些位元設為1。
範例程式 var aValue: UInt8 = 17 var result: UInt8 let mask1: UInt8 = 0x0f // 判斷最右邊的4位元哪一個位元是1 result = aValue & mask1 print("\(aValue) & 00001111 = \(result)") // 判斷最左邊的4位元哪一個位元是1 result = aValue & mask2 print("\(aValue) & 11110000 = \(result)") // 設定最右邊的4位元為1 result = aValue | mask1 print("\(aValue) | 00001111 = \(result)") // 設定最左邊的4位元為1 result = aValue | mask2 print("\(aValue) | 11110000 = \(result)")
輸出結果 17 & 00001111 = 1 17 & 11110000 = 16 17 | 00001111 = 31 17 | 11110000 = 241
Swift運算子的運算優先順序與結合性 運算子 結合性 ! ~ 由右至左 * / % 由左至右 + - << >> ! ~ 由右至左 * / % 由左至右 + - << >> < < = > >= == != & ^ | && || = += -= *= /= %=
18.1.2 用來當做乘、除的功能 我們來敘述位元左移運算子的功能,它好比將某數乘以2n。而位 元右移運算子的功能,則好比是將某數除以2n。
範例程式 let p: UInt16 = 64 var result: UInt16 result = p << 2 print("\(p) << 2 = \(result)") result = p >> 2 print("\(p) >> 2 = \(result)")
輸出結果 64 << 2 = 256 64 >> 2 = 16
18.1.3 用來將兩數對調 一般我們在處理兩數對調時,需要藉助一暫時的變數。 但若以位元運算子 ^,則不需要有暫時的變數。
範例程式 var myScore = 100, yourScore = 80 print("對調前:myScore = \(myScore), yourScore = \(yourScore)") // 兩數對調動作 myScore = myScore ^ yourScore yourScore = yourScore ^ myScore myScore = myScore ^ yourScore print("對調後:myScore = \(myScore), yourScore = \(yourScore)")
輸出結果 對調前:myScore = 100, yourScore = 80 對調後:myScore = 80, yourScore = 100
18.2 運算子函式 類別和結構提供一些所謂多載運算子 (overloading operator) 來實 作已存在的運算子。 18.2 運算子函式 類別和結構提供一些所謂多載運算子 (overloading operator) 來實 作已存在的運算子。 對於客製化的結構問題則須藉助運算子函式 (operator function)。
18.2.1 多載運算子 + 以下是針對複數 (complex number) 的相加撰寫其相關的運算子函 式。 18.2.1 多載運算子 + 以下是針對複數 (complex number) 的相加撰寫其相關的運算子函 式。 複數包括實數 (real) 與虛數 (imaginary)兩部份。
範例程式 // operator function struct Complex { var a = 0 var b = 0 } func + (complex1: Complex, complex2: Complex) -> Complex { return Complex(a: complex1.a + complex2.a, b: complex1.b + complex2.b) let oneObject = Complex(a: 5, b: 3) let anotherObject = Complex(a: 2, b: 2) let sumComplex = oneObject + anotherObject print("\(sumComplex.a) + \(sumComplex.b)i" )
輸出結果 7 + 5i
18.2.2 prefix與 postfix運算子 來看有關 prefix與 postfix運算子,這些運算子與單元運算子有關, 可能是正、負號運算子或是前置與後繼運算子。
範例程式 // prefix struct Complex { var a = 0 var b = 0 } prefix func - (complexObject: Complex) -> Complex { return Complex(a: complexObject.a , b: -complexObject.b) let oneObject = Complex(a: 5, b: 3) let negativeObject = -oneObject print("\(negativeObject.a)\(negativeObject.b)i" )
輸出結果 5-3i
18.2.3 複合指定運算子 複合指定運算子 (compound assignment operator) 結合等號運算子 (=) 與其它運算子,如算術指定運算子(+=) 即結合算術運算子與等 號運算子,使得加法和指定以一單行的型式表示。 這一類的實作在運算子左邊的變數參數需加上inout。
範例程式 struct Complex { var a = 0 var b = 0 } func + (complex1: Complex, complex2: Complex) -> Complex { return Complex(a: complex1.a + complex2.a, b: complex1.b + complex2.b) func += (complex1: inout Complex, complex2: Complex) { complex1 = complex1 + complex2 var oneObject = Complex(a: 5, b: 3) let anotherObject = Complex(a: 2, b: 2) oneObject += anotherObject print("\(oneObject.a)+\(oneObject.b)i" )
輸出結果 7+5i
18.2.4 客製化運算子 可以使用 operator關鍵字並宣告 prefix 、infix 或postfix來自訂運算 子函式。 18.2.4 客製化運算子 可以使用 operator關鍵字並宣告 prefix 、infix 或postfix來自訂運算 子函式。 例如客製化 +++ 運算子函式,將某一 complex 的實數與虛數分別 自已相加,亦即將實數和虛數乘以 2。
範例程式 // customize operator struct Complex { var a = 0 var b = 0 } func + (complex1: Complex, complex2: Complex) -> Complex { return Complex(a: complex1.a + complex2.a, b: complex1.b + complex2.b) func += (complex1: inout Complex, complex2: Complex) { complex1 = complex1 + complex2 prefix operator +++ prefix func +++ (complex: inout Complex) -> Complex { complex += complex return complex var obj3 = Complex(a: 5, b: 3) let obj4 = +++obj3 print("\(obj3.a)+\(obj3.b)i" ) print("\(obj4.a)+\(obj4.b)i" )
輸出結果 10+6i