Golang 運算子及位運算詳解
什麼是運算子?
運算子用於執行程式程式碼運算,會針對一個以上運算元專案來進行運算。例如:2+3,其運算元是2和3,而運算子則是“+”。
在vb2005中運算子大致可以分為5種類型:算術運算子、位運算子、 關係運算符、賦值運算子、邏輯運算子。
算數運算子
運算子 | 描述 |
---|---|
+ | 相加 |
- | 相減 |
* | 相乘 |
/ | 相除 |
% | 求餘 |
注意: ++(自增)和--(自減)在Go語言中是單獨的語句,並不是運算子。
func main() { a,b := 3,4 fmt.Printf("a 加 b = %d\n",a + b) fmt.Printf("a 減 b = %d\n",a - b) fmt.Printf("a 乘 b = %d\n",a * b) fmt.Printf("a 除 b = %d\n",a / b) }
關係運算符
運算子 | 描述 |
---|---|
== | 檢查兩個值是否相等,如果相等返回 True 否則返回 False。 |
!= | 檢查兩個值是否不相等,如果不相等返回 True 否則返回 False。 |
> | 檢查左邊值是否大於右邊值,如果是返回 True 否則返回 False。 |
>= | 檢查左邊值是否大於等於右邊值,如果是返回 True 否則返回 False。 |
< | 檢查左邊值是否小於右邊值,如果是返回 True 否則返回 False。 |
<= | 檢查左邊值是否小於等於右邊值,如果是返回 True 否則返回 False。 |
package main import "fmt" func main() { a,4 //fmt.Println("a == b?",a == b) // a == b? false //fmt.Println("a != b?",a != b) // a != b? true //fmt.Println("a > b?",a > b ) // a > b? true //fmt.Println("a >= b?",a >= b) // a >= b? false //fmt.Println("a < b?",a < b ) // a >= b? true //fmt.Println("a <= b?",a <= b ) // a <= b? true }
邏輯運算子
運算子 | 描述 |
---|---|
&& | 邏輯 AND 運算子。 如果兩邊的運算元都是 True,則為 True,否則為 False。 |
|| | 邏輯 OR 運算子。 如果兩邊的運算元有一個 True,則為 True,否則為 False。 |
! | 邏輯 NOT 運算子。 如果條件為 True,則為 False,否則為 True。 |
package main import "fmt" func main() { a,b := true,false fmt.Println("a && b ?",a && b) // a && b ? false fmt.Println("a || b ?",a || b) // a || b ? true fmt.Println(" !a ?",!a) // !a ? false fmt.Println(" !b ?",!b) // !b ? true }
位運算子
常見進位制:
二進位制:只有 0 和 1,Go語言中不能直接使用二進位制表示整數;
八進位制:0-7,以數字 0 開頭;
十進位制:0-9;
十六進位制:0-9 以及 A-F,以 0X 開頭,A-F 以及 X 不區分大小寫。
package main import "fmt" func main() { a := 10 // 二進位制 fmt.Printf("%b\n",a) // 1010 // 八進位制 fmt.Printf("%o\n",a) // 12 // 十進位制 fmt.Printf("%d\n",a) // 10 // 十六進位制 fmt.Printf("%x\n",a) // a }
任意進位制轉換為十進位制
二進位制轉十進位制:從最低位開始,每個位上數乘以 2 的位數減 1 次方然後求和。
1011 = 120 + 121 + 022 + 123 = 11
八進位制轉十進位制:從最低位開始,每個位上數乘以 8 的位數減 1 次方然後求和。
0123 = 380 + 281 + 182 + 083 = 83
其他進位制互轉:
二進位制轉換八進位制:將二進位制數從低位開始,每三位一組,轉換成八進位制數即可;
二進位制轉十六進位制:將二進位制數從低位開始,每四位一組,轉換成十六進位制數即可;
八進位制轉換二進位制:將八進位制數每 1 位轉換成一個 3 位的二進位制數(首位 0 除外);
十六進位制轉二進位制:將十六進位制每 1 位轉換成對應的一個 4 位的二進位制數即可。
反碼補碼
對於有符號數而言,二進位制的最高為是符號位:0 表示正數,1 表示負數。
短除法進行進位制轉變
十進位制的10-> 二進位制:
二進位制的1011 -> 十進位制
想要詳細瞭解其原理的可以參考短除法相關說明
位運算子對整數在記憶體中的二進位制位進行操作。
運算子 | 描述 |
---|---|
& | 參與運算的兩數各對應的二進位相與。 (兩位均為1才為1) |
| | 參與運算的兩數各對應的二進位相或。 (兩位有一個為1就為1) |
^ | 參與運算的兩數各對應的二進位相異或,當兩對應的二進位相異時,結果為1。 (兩位不一樣則為1) |
<< | 左移n位就是乘以2的n次方。 “a<<b”是把a的各二進位全部左移b位,高位丟棄,低位補0。 |
>> | 右移n位就是除以2的n次方。 “a>>b”是把a的各二進位全部右移b位。 |
XOR - 異或:相同為0,不同為1.也可用“進位加法”來理解
x ^ 0 = X x ^ 1s = ~x # 1s = ~ 0 x ^ (~x) = 1s x ^ x = 0 c = a ^ b => a ^ c = b,b ^c = a # 交換兩數 a ^ b ^ c = a ^(b ^ c) = (a ^ b) ^c # associative // 指定未知的位運算 . 將x最右邊的n位請零: x & (~0 << n ) . 獲取x的第n位值(0 或 1): (x >> n)& 1 . 獲取x的第n位的冪值:x & (1 << n) . 僅將第n位置為 1: x | (1 << n) . 僅將第n位置為0:x & (~1(1 << n)) . 將x最高位至第n位(含)清零:x & ((1 << n) - 1) // 實戰位運算要點 // 判斷奇偶性 x % 2 == 1 - > (x & 1) == 1 x & 2 == 0 -> (x&1) == 0 // 清零最低位的1 x = x & (x - 1) // 得到最低位的1 x & ~x x & ~ x = > 0
為了更清晰的觀察其變化,我們使用二進位制來進行演示
package main import "fmt" func main() { a,b := 13,21 fmt.Printf("a:%b & %b = %b\n",a,b,a & b) fmt.Printf("a:%b | %b = %b\n",a | b) fmt.Printf("a:%b ^ %b = %b\n",a ^ b) fmt.Printf("a:%b ^ %b = %b\n",a ^ b) // 左移 // 二進位制表示 fmt.Printf("%b << %b = %b\n",2,2<<2) // 10 << 10 = 1000 // 十進位制 fmt.Printf("%d << %d = %d\n",2<<2) // 2 << 2 = 8 // 右移 // 二進位制 fmt.Printf("%b >> %b = %b\n",2>>2) // 10 >> 10 = 0 // 十進位制 fmt.Printf("%d >> %d = %d\n",2>>2) // 2 >> 2 = 0 }
賦值運算子
運算子 | 描述 |
---|---|
= | 簡單的賦值運算子,將一個表示式的值賦給一個左值 |
+= | 相加後再賦值 |
-= | 相減後再賦值 |
*= | 相乘後再賦值 |
/= | 相除後再賦值 |
%= | 求餘後再賦值 |
<<= | 左移後賦值 |
>>= | 右移後賦值 |
&= | 按位與後賦值 |
|= | 按位或後賦值 |
^= | 按位異或後賦值 |
運算子優先順序
運算子優先順序確定表示式中的分組。這會影響表示式的計算方式。某些運算子比其他運算子具有更高的優先順序; 例如,乘法運算子比加法運算子有更高的優先順序。
當同級別的運算子出現在同一個表示式中,從左到右的順序計算,比如乘除一起,不管是乘在前面還是除在前面都是從左到右計算乘、除運算子。加減亦是如此。
例如:x = 7 + 3 * 2; 這裡,計算結果x被分配13,而不是20,因為運算子 *具有比+有更的優先順序,所以它首先乘以3 * 2,然後加上7。
這裡,具有最高優先順序的運算子放在表的頂部,具有最低優先順序的運算子出現在底部。 在表示式中,將首先計算較高優先順序運算子。
分類 | 描述 | 關聯性 |
---|---|---|
字尾 | ()[]->.++ – | 左到右 |
一元 | + -!~++ --(type)*&sizeof | 右到左 |
乘法 | */ % | 左到右 |
加法 | + - | 左到右 |
移位 | <<>> | 左到右 |
關係 | <<=>>= | 左到右 |
相等 | ==!= | 左到右 |
按位AND | & | 左到右 |
按位XOR | ^ | 左到右 |
按位OR | | | 左到右 |
邏輯AND | && | 左到右 |
邏輯OR | || | 左到右 |
條件 | ?: | 右到左 |
分配 | =+=-=*=/= %=>>= <<= &= ^= |= | 右到左 |
逗號 | , | 左到右 |
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援我們。如有錯誤或未考慮完全的地方,望不吝賜教。