In low-level programming, it is common to work at the bit level. This was true in earlier days of computing and even relevant today. Most popular languages kept provisions for bit level operations, not only as a legacy, but also as a frequently used feature in their arsenal. Direct bit-level operations have their uses in cryptography, system level programming, image processing, and so forth. Here, in this Golang programming tutorial, we will go into the details of bitwise operators and how to work with them in Go.

**Read:** Best Online Courses to Learn Go and Golang

## Golang Bitwise Operators

Go provides the following bitwise operators:

**&**: Bitwise AND**|**: Bitwise OR**^**: Bitwise XOR**&^**: Bit clear (AND NOT)**<<**: Left shift**>>**: Right shift

Bitwise operators in Go deal with bit **– 0** and **1** and work only on integer variables having bit patterns of equal length. The format-string **%b** is used for bit-representation. Here is a quick code example showing how to take user input and format it as a binary number in Go:

package main import "fmt" func main() { var i int fmt.Printf("Enter number:") fmt.Scanf("%d", &i) fmt.Printf("Number %d in binary is %b", i, i) }

Running this code in your integrated development environment (IDE) gives us the following output:

Enter number:34 Number 34 in binary is 100010

Here we have input a number into an integer variable through **fmt.Scanf** and used the format-string **%d** to print its binary form.

### Use of Bit Level Operations in Go

Below are some use cases for when a developer might use bit level operations in Go:

- Since bitwise operators work on bit fields they are particularly efficient in presenting something that has “
**yes**” and “**no**” or “**true**” or “**false**” properties. For example, if a programmer wants to give or revoke permission to a file (**read**,**write**,**execute**), instead of storing the bytes of information for the permission, we can use only three bits such as**101 = (read, execute only)**or**100 (read only)**. This saves a lot of space. - In a network transmission or a communication over ports/sockets that involve parity and checksums, which depend heavily on bit operation
- All encryption and compression algorithms work on a bit level and heavily use bitwise operators
- Working with images or in graphics programming, bit level operations help a lot, particularly the
**XOR**operator has many interesting uses in graphics and image processing - Creating logic gates, circuit development, device drivers, finite state machines, and mathematics all have numerous uses for bitwise operators

## The & (AND) Operator in Go

The **&** operator in Go performs **AND** operations between two integer numbers provided as an operand. The bitwise **AND** operation has the following characteristics:

Note that the result is **1** *only* when both **x** and **y** have value, otherwise it results in a **0** value. The **AND** operation can be used to clear – or set to **0** – certain bit positions in a number. This idea can be used in numerous creative ways. For example, if a programmer wants to find a number **ODD** or **EVEN**, they may use the **&** operator in the following way:

x := 125 if (x & 0x1) > 0 { fmt.Println("ODD") } else { fmt.Println("EVEN") }

This trick works because every **ODD** number has **1** as the least significant bit (LSB) and the **AND** operation will clear all the bits except the LSB. As such, the result of the **if-condition** will be **true** if the value **ANDed** with **0x1** is greater than **0**, which means the number is **ODD** and **false** otherwise.

## The | (OR) Operator in Go

The **|** operator in Go performs **OR** operations between two integer numbers provided as an operand. The bitwise **OR** operation has the following characteristics:

Note that, in this case, the result is **1** when at least any one input is **1**, and **0** otherwise. This property can be used to set certain bits, unlike **AND**, which can be used to clear certain bits. Suppose we want to set the LSB of a decimal number **10** (in binary **1010**). After setting the LSB, the result should be **11** (in binary **1011**). Here is the code to perform this task:

var set_bit uint32 = 0x1 var value uint32 = 0xA fmt.Printf("%b", value|set_bit)

So, if **&** (**AND**) operation can be used for *clearing* bits, **|** (**OR**) can be used for *setting* bits.

**Read:** Understanding Mathematical Operators in Go

## The ^ (XOR) Operator in Go

The **^** operator in Go performs **OR** operations between two integer numbers provided as an operand. The bitwise **OR** operation has the following characteristics:

In this case, the output is 1 *only* when both the input values are different. If both input values are the same, it would result in **0** when **XORed**. The **XOR** operator has many interesting uses in computing. It is particularly used to toggle values, such as changing value **0** to 1 and 1 to **0** in a sequence of bits. A common trick with **XOR** is to swap values of two variables without using a third/another variable. Here is a code example showing how to execute this idea in Go:

x := 5 y := 6 fmt.Printf("\nBefore swap: x=%d,y=%d", x, y) x = x ^ y y = x ^ y x = x ^ y fmt.Printf("\nAfter swap x=%d,y=%d", x, y)

The above Golang code exchanges (or swaps) the value stored in **x** to **y** and **y** to x using the **XOR** operator.

## The &^ (AND NOT) Operator in Go

The **&^ (AND NOT)** operator in Go is a bit interesting because the actual operator is **^** and the **&^** is just used to separate it from the **XOR** operator. The reason is that, unlike C/C++ which have a dedicated unary **NOT** operator represented by the exclamation sign (**!**), Go does not have a bitwise **NOT** operator (not to be confused with the **!** Logical not operator). Therefore, to negate anything, programmers can use the same **^ (XOR)** operator acting as a bitwise **NOT**. The bitwise **NOT** actually produces one’s complement of a number. So, a given bit **x** and **^x** would be a complement of each other. Here is a simple code example showing how to use the **&^ (AND NOT)** operator in Go:

var x uint8 = 129 fmt.Printf("\n x=%b,^x=%b", x, ^x)

## The << (left-shift) and >> (right-shift) Operators in Go

The **<<** left-shift and **>>** right-shift operators in Go shift the number of bit positions to the left by inserting **0** as the LSB, and right by inserting **0** to the MSB, respectively. For example, a given integer **x** can be shifted left by **n** bits or shifted right by n bits as follows:

x << n, shifts x to the left by n bits x >> n, shift x to the right by n bits

Among many of its interesting uses in programming, if programmers left shift a number by **1** bit, it gives a result of the value multiplied by **2**. Similarly, if we right shift a number by **1** bit, we get a quotient of the value divided by **2**. Here is a quick code example illustrating the idea:

var x uint8 = 10 fmt.Printf("\n%d x 2 = %d", x, x<<1) fmt.Printf("\n%d / 2 = %d", x, x>>1)

## Final Thoughts on Bitwise Operators in Go

Sometimes developers get confused when we see similar operations are performed with bitwise and logical operators. To allay such a confusion, bitwise operators always produce numeric bit values, while logical operators produce only two values – either **true** or **false**, which are non-numeric. This simple distinction makes it all clear. Bitwise operations have numerous interesting and tricky uses. Sometimes a lengthy logic can be made short and quick using bitwise operators. Working with bitwise operators in Go and Golang not only has a low-level feel, but is also quite fun to work with.

Read more Go and Golang programming tutorials and software development tips.