Skip to content

bitewise

位运算的英文是 Bitwise Operations。这些操作直接作用于整数的二进制表示(位)。位运算通常包括以下几种常见类型:

常见的位运算及其英文

  1. 按位与(AND): Bitwise AND (&)

    • 对应位都为 1 时,结果为 1,否则为 0。
  2. 按位或(OR): Bitwise OR (|)

    • 对应位只要有一个为 1,结果就为 1。
  3. 按位异或(XOR): Bitwise XOR (^)

    • 对应位相同则结果为 0,相异则结果为 1。
  4. 按位取反(NOT): Bitwise NOT (^ 单独符号)

    • 取反操作,将每个位的值从 1 变成 0,从 0 变成 1。
  5. 左移: Left Shift (<<)

    • 将二进制数的所有位向左移动指定的位数,右侧用 0 填充。
  6. 右移: Right Shift (>>)

    • 将二进制数的所有位向右移动指定的位数,左侧根据符号位(无符号类型用 0 填充)进行填充。

位运算的其他相关术语

  • 位掩码 (Bitmask): 用于从数据中提取特定位或设置特定位的值。通常通过与运算(&)或者或运算(|)实现。

  • 二进制表示 (Binary Representation): 用于描述数字在内存中的存储方式,通常由 0 和 1 组成。

  • 补码 (Two's Complement): 用于表示带符号整数的一种方法。在计算机中,负数常用补码表示。

位运算常用于需要直接操作数据二进制位的场景,像是优化性能、实现快速计算、处理硬件、加密解密等。

在 Go 语言中,位运算是一种直接操作数字在内存中的二进制位的操作。位运算通常用于处理低层次的操作,例如控制硬件、优化性能或处理某些算法问题。Go 提供了几种常用的位运算操作符。

Go 中的位运算符

  1. 按位与(AND) &

    • 对应位都为 1 时,结果为 1,否则为 0。
    • 例如:1101 & 1011 = 1001
    go
    package main
    import "fmt"
    
    func main() {
        a := 5   // 0101
        b := 3   // 0011
        fmt.Println(a & b)  // 1, 0101 & 0011 = 0001
    }
  2. 按位或(OR) |

    • 对应位只要有一个为 1,结果就为 1。
    • 例如:1101 | 1011 = 1111
    go
    package main
    import "fmt"
    
    func main() {
        a := 5   // 0101
        b := 3   // 0011
        fmt.Println(a | b)  // 7, 0101 | 0011 = 0111
    }
  3. 按位异或(XOR) ^

    • 对应位相同则结果为 0,相异则结果为 1。
    • 例如:1101 ^ 1011 = 0110
    go
    package main
    import "fmt"
    
    func main() {
        a := 5   // 0101
        b := 3   // 0011
        fmt.Println(a ^ b)  // 6, 0101 ^ 0011 = 0110
    }
  4. 按位取反(NOT) ^(单一符号)

    • 取反操作,即对每个二进制位执行反转操作,将 0 变为 1,1 变为 0。
    • 例如:^1101 = 0010
    go
    package main
    import "fmt"
    
    func main() {
        a := 5   // 0101
        fmt.Println(^a)  // -6, ^0101 = 1010 (二进制补码表示)
    }

    注意:在 Go 中,^ 作为按位取反运算符,操作的是整型变量的补码。

  5. 左移(Left Shift) <<

    • 将二进制数的位向左移动,右侧补 0,相当于乘以 2 的指定次方。
    • 例如:1010 << 2 = 100000
    go
    package main
    import "fmt"
    
    func main() {
        a := 5  // 0101
        fmt.Println(a << 2)  // 20, 0101 << 2 = 10100
    }
  6. 右移(Right Shift) >>

    • 将二进制数的位向右移动,左侧根据符号位(对于无符号类型为 0)进行填充,相当于除以 2 的指定次方。
    • 例如:10100 >> 2 = 0101
    go
    package main
    import "fmt"
    
    func main() {
        a := 20  // 10100
        fmt.Println(a >> 2)  // 5, 10100 >> 2 = 0101
    }

位运算的应用

位运算在许多实际问题中非常有用,特别是在处理大规模数据时,或者当需要直接操作二进制位时。以下是一些常见的位运算应用场景:

  1. 判断奇偶

    • 通过 & 运算可以轻松判断一个数是奇数还是偶数。偶数的最低位为 0,奇数的最低位为 1。
    go
    package main
    import "fmt"
    
    func main() {
        a := 5  // 奇数
        if a&1 == 1 {
            fmt.Println(a, "is odd")
        } else {
            fmt.Println(a, "is even")
        }
    }
  2. 交换两个数(无需临时变量):

    • 使用异或运算符 ^ 可以交换两个整数的值。
    go
    package main
    import "fmt"
    
    func main() {
        a := 3
        b := 5
        fmt.Println("Before swap:", a, b)
    
        a = a ^ b
        b = a ^ b
        a = a ^ b
    
        fmt.Println("After swap:", a, b)
    }
  3. 提取某一位

    • 使用位运算提取整数中的某一位,可以通过 & 和位掩码进行操作。
    go
    package main
    import "fmt"
    
    func main() {
        a := 5  // 0101
        fmt.Println(a & (1 << 2))  // 4, 提取第 3 位(从右到左,索引从 0 开始)
    }
  4. 计算 2 的幂

    • 左移操作可以计算 2 的幂次方。
    go
    package main
    import "fmt"
    
    func main() {
        n := 3
        fmt.Println(1 << n)  // 8, 2^3
    }
  5. 快速计算除以 2 或乘以 2

    • 对于无符号整数,右移相当于除以 2,左移相当于乘以 2。
    go
    package main
    import "fmt"
    
    func main() {
        a := 16
        fmt.Println(a >> 1)  // 8, 除以 2
        fmt.Println(a << 1)  // 32, 乘以 2
    }

总结

位运算在 Go 中是通过一系列运算符实现的,常见的有按位与、按位或、按位异或、按位取反、左移和右移等。位运算能够高效地解决一些低级别的数据处理问题,特别是在优化算法和控制硬件时非常有用。掌握位运算对于编写高效代码和处理一些特殊问题非常重要。