Bitwise operations are a fundamental concept in computer science that allow you to manipulate bits directly. They're used in scenarios where performance is key, like systems programming, graphics, cryptography, and network protocols. In this article, we'll explore how to perform bitwise operations on integers in the Go programming language.
Getting Started with Bitwise Operations in Go
Before diving into examples, let's review the essential bitwise operators available in Go:
&: AND operator|: OR operator^: XOR operator~: NOT operator<<: Left shift operator>>: Right shift operator
Basic Code Examples
Let's look at basic examples of each operator.
package main
import "fmt"
func main() {
a := 60 // 0011 1100 in binary
b := 13 // 0000 1101 in binary
// AND
fmt.Printf("a & b = %d\n", a & b) // 12 = 0000 1100
// OR
fmt.Printf("a | b = %d\n", a | b) // 61 = 0011 1101
// XOR
fmt.Printf("a ^ b = %d\n", a ^ b) // 49 = 0011 0001
// NOT
fmt.Printf("^a = %d\n", ^a) // -61 = 1100 0011 (in two's complement form)
// Left shift
fmt.Printf("a << 2 = %d\n", a << 2) // 240 = 1111 0000
// Right shift
fmt.Printf("a >> 2 = %d\n", a >> 2) // 15 = 0000 1111
}
Intermediate Concepts
Combining operations enables advanced manipulation of individual bits.
package main
import "fmt"
func main() {
flag := 0 // A flag variable initialized to 0
// Using OR to set a bit (e.g. setting 4th bit)
mask := 1 << 3
flag |= mask
fmt.Printf("Set 4th Bit: %08b\n", flag)
// Using AND to clear a bit (e.g. clearing 4th bit)
flag &= ^mask
fmt.Printf("Cleared 4th Bit: %08b\n", flag)
// Toggle a bit (e.g. toggle 2nd bit)
flag ^= 1 << 1
fmt.Printf("Toggle 2nd Bit: %08b\n", flag)
// Checking a specific bit (2nd bit)
bit := (flag & (1 << 1)) != 0
fmt.Printf("2nd Bit is set: %t\n", bit)
}
Advanced Techniques
In more complex systems, bitwise operations can optimize performance.
package main
import (
"fmt"
"math/bits"
)
func main() {
// Counting bits set to 1
n := uint(13) // 0000 1101 in binary
count := bits.OnesCount(n)
fmt.Printf("Number of 1 bits: %d\n", count)
// Rotate bits (rotate-left)
x := uint32(1)
fmt.Printf("Before Rotate-Left: %032b\n", x)
x = bits.RotateLeft32(x, 2)
fmt.Printf("After Rotate-Left: %032b\n", x)
// Checking parity - whether the number of 1s is odd or even
parity := bits.OnesCount(n)%2 == 0
fmt.Printf("Parity (even number of 1s): %t\n", parity)
}
Bitwise operations in Go are powerful tools especially when you need to perform operations directly at the bit level swiftly and effectively. Understanding and mastering these operations can greatly improve the performance of your application where bit manipulation is needed.