1. 程式人生 > 程式設計 >Golang 運算子及位運算詳解

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 表示負數。

短除法進行進位制轉變

Golang 運算子及位運算詳解

十進位制的10-> 二進位制:

Golang 運算子及位運算詳解

二進位制的1011 -> 十進位制

Golang 運算子及位運算詳解

想要詳細瞭解其原理的可以參考短除法相關說明

位運算子對整數在記憶體中的二進位制位進行操作。

運算子 描述
& 參與運算的兩數各對應的二進位相與。 (兩位均為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 || 左到右
條件 ?: 右到左
分配 =+=-=*=/= %=>>= <<= &= ^= |= 右到左
逗號 , 左到右

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援我們。如有錯誤或未考慮完全的地方,望不吝賜教。