How do I get the bits from a byte in golang?

fmt.Sprintf("%08b", byte(1)) is great idea. It shows you, how the number is store internally. And example to compute hamming distance (very boring) could be:

package main

import (
    "fmt"
)

func HamDist(n1,n2 uint8) uint8 {
    var w uint8 = 0
    if n1&1 != n2&1 {
        w++
    }
    if n1&2 != n2&2 {
        w++
    }
    if n1&4 != n2&4 {
        w++
    }
    if n1&8 != n2&8 {
        w++
    }
    if n1&16 != n2&16 {
        w++
    }
    if n1&32 != n2&32 {
        w++
    }
    if n1&64 != n2&64 {
        w++
    }
    if n1&128 != n2&128 {
        w++
    }
    return w
}

func main() {
    fmt.Println(HamDist(255,0))
}

And now tasks for you:

  1. rewrite the code using a loop
  2. extend program to compute hamming distance of 16-bit number
  3. please think what xor operator does and whether should not be possible compute HammingDistance easier, if you has defined a function that computes Hamming weight.

You can see the visual representation of bits using fmt.Sprintf(%08b, ..) as others have already suggested.

However, if you want to use the bits in operations, such as for calculating the Hamming distance, you'll need to use bitwise operators.

To calculate the nth bit of a byte, you'll need to bitwise AND that byte with another byte whose nth bit is set to 1 and the rest to 0 (aka masking). In other words, that other byte (mask) is the number 2^n-1.

For example, to find the 1st bit of the number 13 (00001101), we would have to mask it with 2^0 = 1 (00000001). We compare the output of performing bitwise AND on both numbers to the mask. If they are equal, it means that the nth bit is 1, otherwise it is 0. We continue like this and find all the bits. Illustrated in Go code:

fmt.Print(13 & 1) // Output: 1 -> 1
fmt.Print(13 & 2) // Output: 2 -> 0
fmt.Print(13 & 4) // Output: 4 -> 1
fmt.Print(13 & 8) // Output: 8 -> 1
// Not necessary to continue, but shown for the sake of the example
fmt.Print(13 & 16) // Output: 0 -> 0
fmt.Print(13 & 32) // Output: 0 -> 0
fmt.Print(13 & 64) // Output: 0 -> 0
fmt.Print(13 & 128) // Output: 0 -> 0

Therefore, 13 in binary is 00001101

Here's a function I wrote recently for calculating the Hamming distance between two arrays of bytes. Just pass an array consisting of a single byte each in your case

func hamming(a, b []byte) (int, error) {
    if len(a) != len(b) {
        return 0, errors.New("a b are not the same length")
    }

    diff := 0
    for i := 0; i < len(a); i++ {
        b1 := a[i]
        b2 := b[i]
        for j := 0; j < 8; j++ {
            mask := byte(1 << uint(j))
            if (b1 & mask) != (b2 & mask) {
                diff++
            }
        }
    }
    return diff, nil
}

Go Playground: https://play.golang.org/p/O1EGdzDYAn

Tags:

Go