三亚市网站建设_网站建设公司_导航菜单_seo优化
2026/1/17 14:01:31 网站建设 项目流程

Go 语言位运算符全面总结

Go 语言位运算符全面总结

📊 位运算符速查表

运算符 名称 示例 结果 记忆技巧
& 位与 (AND) 1010 & 1100 1000 都为1才是1
| 位或 (OR) 1010 | 1100 1110 有1就是1
^ 位异或 (XOR) 1010 ^ 1100 0110 不同为1
&^ 位清除 (AND NOT) 1010 &^ 1100 0010 清除右边为1的位
<< 左移 0011 << 2 1100 乘以2^n
>> 右移 1100 >> 2 0011 除以2^n
^(一元) 位取反 (NOT) ^1010 ...0101 0变1,1变0

🔍 详细功能解析

1. 位与 & - 按位与

// 功能:两个位都为1时结果为1,否则为0
func bitwiseAND() {a := 0b1010  // 10b := 0b1100  // 12result := a & b  // 0b1000 = 8fmt.Printf("%04b & %04b = %04b\n", a, b, result)// 输出: 1010 & 1100 = 1000// 应用场景:// 1. 检查特定位是否为1flags := 0b1101mask := 0b0100  // 检查第2位if flags & mask != 0 {fmt.Println("第2位是1")}// 2. 清除某些位(通过与0相与)clearMask := ^0b0010  // 1110...1101cleared := flags & clearMask  // 清除第1位
}

2. 位或 | - 按位或

// 功能:两个位有1个为1时结果为1
func bitwiseOR() {a := 0b1010  // 10b := 0b1100  // 12result := a | b  // 0b1110 = 14fmt.Printf("%04b | %04b = %04b\n", a, b, result)// 输出: 1010 | 1100 = 1110// 应用场景:// 1. 设置特定位为1flags := 0b0000setMask := 0b0010flags = flags | setMask  // 设置第1位为1// 2. 组合多个标志read := 1 << 0  // 0001write := 1 << 1 // 0010exec := 1 << 2  // 0100permissions := read | write | exec  // 0111
}

3. 位异或 ^ - 按位异或

// 功能:两个位不同时结果为1,相同时为0
func bitwiseXOR() {a := 0b1010  // 10b := 0b1100  // 12result := a ^ b  // 0b0110 = 6fmt.Printf("%04b ^ %04b = %04b\n", a, b, result)// 输出: 1010 ^ 1100 = 0110// 应用场景:// 1. 切换位(0变1,1变0)flags := 0b1010toggleMask := 0b0011toggled := flags ^ toggleMask  // 1001// 2. 交换两个数(不用临时变量)x, y := 5, 9x = x ^ yy = x ^ yx = x ^ y// 现在 x=9, y=5// 3. 加密/解密(相同密钥两次异或得到原值)data := 42key := 123encrypted := data ^ keydecrypted := encrypted ^ key  // 变回42
}

4. 位清除 &^ - AND NOT(Go特有)

// 功能:清除a中在b里为1的位
func bitwiseAndNot() {a := 0b1010  // 10b := 0b1100  // 12result := a &^ b  // 0b0010 = 2fmt.Printf("%04b &^ %04b = %04b\n", a, b, result)// 输出: 1010 &^ 1100 = 0010// 等价于:a & (^b)// 但比 ^ 优先级高,更安全// 应用场景:// 1. 清除特定标志位flags := 0b1111clearMask := 0b1010cleared := flags &^ clearMask  // 0101// 2. 从集合中移除元素(差集)setA := 0b1101  // 元素 {0, 2, 3}setB := 0b0110  // 元素 {1, 2}diff := setA &^ setB  // 1101,移除交集
}

5. 左移 << - 向左移位

// 功能:所有位向左移动,右侧补0
func leftShift() {x := 0b0001  // 1result := x << 3  // 0b1000 = 8fmt.Printf("%04b << 3 = %04b (%d)\n", x, result, result)// 输出: 0001 << 3 = 1000 (8)// 应用场景:// 1. 快速乘以2的幂n := 5doubled := n << 1  // 10times8 := n << 3   // 40// 2. 创建位掩码bit3 := 1 << 3  // 00001000bits2and3 := (1<<2) | (1<<3)  // 00001100// 3. 标志位定义const (FlagA = 1 << iota  // 1FlagB              // 2FlagC              // 4FlagD              // 8)
}

6. 右移 >> - 向右移位

// 功能:所有位向右移动
func rightShift() {x := 0b1000  // 8result := x >> 2  // 0b0010 = 2fmt.Printf("%04b >> 2 = %04b (%d)\n", x, result, result)// 输出: 1000 >> 2 = 0010 (2)// 注意:有符号数和无符号数右移行为不同!// 无符号数:左侧补0// 有符号数:左侧补符号位(算术右移)var u uint8 = 0b10000000  // 128var s int8 = -128          // 二进制也是10000000fmt.Printf("无符号: %08b >> 1 = %08b (%d)\n", u, u>>1, u>>1)fmt.Printf("有符号: %08b >> 1 = %08b (%d)\n", byte(s), s>>1, s>>1)// 应用场景:// 1. 快速除以2的幂(无符号数)n := 16half := n >> 1  // 8// 2. 提取特定位value := 0b11010110bit3 := (value >> 3) & 1  // 提取第3位// 3. 分解字节rgb := 0xFF3366r := (rgb >> 16) & 0xFF  // 红色分量g := (rgb >> 8) & 0xFF   // 绿色分量b := rgb & 0xFF          // 蓝色分量
}

7. 位取反 ^ - 一元运算符

// 功能:所有位取反(0变1,1变0)
func bitwiseNOT() {x := uint8(0b00001111)  // 15result := ^x  // 0b11110000 = 240fmt.Printf("^%08b = %08b\n", x, result)// 输出: ^00001111 = 11110000// 注意:Go中^既是一元也是二元运算符// 一元:位取反// 二元:异或// 应用场景:// 1. 创建掩码的反码mask := 0b00001111invertedMask := ^mask  // 11110000// 2. 求补码(有符号数)// Go中整数以补码形式存储// 3. 清除特定位(与&^配合)flags := 0b1111keepMask := 0b1100  // 保留高2位cleared := flags & ^keepMask  // 清除低2位
}

📊 组合使用示例

示例1:权限系统

// 使用位运算实现权限控制
const (Read   = 1 << iota  // 0001Write               // 0010Execute             // 0100Delete              // 1000
)type User struct {permissions byte
}func (u *User) addPermission(perm byte) {u.permissions |= perm  // 设置位
}func (u *User) removePermission(perm byte) {u.permissions &^= perm  // 清除位
}func (u *User) hasPermission(perm byte) bool {return u.permissions & perm != 0  // 检查位
}func (u *User) togglePermission(perm byte) {u.permissions ^= perm  // 切换位
}

示例2:位标志操作

func bitFlagOperations() {// 初始化标志var flags uint8 = 0// 设置标志flags |= 0b00000001  // 设置第0位flags |= 0b00000100  // 设置第2位fmt.Printf("设置后: %08b\n", flags)  // 00000101// 检查标志if flags & 0b00000100 != 0 {fmt.Println("第2位已设置")}// 清除标志flags &^= 0b00000001  // 清除第0位fmt.Printf("清除后: %08b\n", flags)  // 00000100// 切换标志flags ^= 0b00001000  // 切换第3位fmt.Printf("切换后: %08b\n", flags)  // 00001100// 获取所有设置的位for i := 0; i < 8; i++ {if flags & (1 << i) != 0 {fmt.Printf("位 %d 已设置\n", i)}}
}

示例3:颜色操作(RGBA)

func colorOperations() {// 32位ARGB颜色:A R G B 各8位color := uint32(0xFF336699)  // Alpha=FF, R=33, G=66, B=99// 提取各分量alpha := (color >> 24) & 0xFFred := (color >> 16) & 0xFFgreen := (color >> 8) & 0xFFblue := color & 0xFFfmt.Printf("A=%02X R=%02X G=%02X B=%02X\n", alpha, red, green, blue)// 修改分量// 将红色分量改为0xAAcolor = (color & 0xFF00FFFF) | (0xAA << 16)// 降低亮度(所有分量减半)color = ((color >> 1) & 0x7F7F7F7F) | (alpha << 24)// 创建新颜色newColor := (0xFF << 24) | (0x12 << 16) | (0x34 << 8) | 0x56
}

🎯 优先级和结合性

优先级 运算符 说明
1 ^(一元) 位取反
2 << >> 移位
3 & 位与
4 ^(二元) 位异或
5 | 位或
6 &^ 位清除

使用括号明确优先级

// 容易混淆的表达式
result1 := a & b ^ c   // (a & b) ^ c
result2 := a & (b ^ c) // 不同的结果!// 总是使用括号使意图明确
clear := (a & ^b)      // 与 a &^ b 相同

💡 实用技巧

1. 判断奇偶性

func isEven(n int) bool {return n & 1 == 0  // 比 n%2 == 0 更快
}

2. 交换两个变量

func swap(a, b int) (int, int) {a ^= bb ^= aa ^= breturn a, b  // 不用临时变量
}

3. 判断是否是2的幂

func isPowerOfTwo(n int) bool {return n > 0 && (n & (n-1)) == 0
}

4. 获取最低位的1

func lowestSetBit(n int) int {return n & -n  // 如:1010 & 0110 = 0010
}

5. 统计1的个数(Brian Kernighan算法)

func countOnes(n uint) int {count := 0for n != 0 {n &= n - 1  // 清除最低位的1count++}return count
}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询