Fragment Description:



The bitwise operations in Go.
The use of <<:
for right shifts, if the left operand is unsigned, Go performs logical shift; if signed, an arithmetic shift (shifting left by one is the same as multiplication by 2, and shifting right by one is the same as dividing by two, discarding any remainder:
8 >> 1 gives 4, and 8 << 1 gives 16).
Remember:
always go for multiplication when you are looking to multiply.
And go for bit shifting when you want to move bits.
Do what is simplest to understand.
If you were writing assembly directly it can be useful...
or if you were writing an optimizing compiler, again it could be useful.
But outside of those two cases its a trick that obscures what you are doing and makes the next programmer (who is an axe murder who knows where you live) curse your name and think of taking up a hobby.


bitwiseOperations

Go Playground

Last update, on 2015, Fri 27 Nov, 11:57:25

/* ... <== see fragment description ... */

package main

import (
    "fmt"
)

func main() {
    var x uint = 1<<1 | 1<<3 | 1<<6
    var y uint = 1<<1 | 1<<2
    // 08 modifies %b to pad the result with exactly 8 digits
    fmt.Printf("x =\t%08b\n", x) //  "01001010", the set {1, 3, 6}
    fmt.Printf("y =\t%08b\n", y) //  "00000110", the set {1, 2}
    fmt.Println("-----")
    // AND: x&y = 00000010, the intersection {1}
    fmt.Printf("x&y =\t%08b\tthe intersection: AND\n", x&y)
    // OR: x|y = 01001110, the union {1, 2, 3, 6}
    fmt.Printf("x|y =\t%08b\tthe union: OR\n", x|y)
    // XOR: x^y = 01001100, the symmetric difference {2, 3, 6}
    fmt.Printf("x^y =\t%08b\tthe symmetric difference: XOR\n", x^y)
    // NOT: x&^y = 01001000, the difference {3, 6}
    fmt.Printf("x&^y =\t%08b\tthe difference: NOT\n", x&^y)
    fmt.Println("-----")
    fmt.Println("members of x that are not 0")
    fmt.Printf("x =\t%08b\n", x)
    for i := uint(0); i < 8; i++ {
        if x&(1<<i) != 0 { // membership test
            fmt.Println(i)
        }
    }

    fmt.Println("-----")
    fmt.Printf("x is =\t%08b\n", x)
    fmt.Printf("x<<1 =\t%08b\n", x<<1) //    x<<1 = 10010100, the set {2, 4, 7}
    fmt.Printf("x>>1 =\t%08b\n", x>>1) //    x>>1 = 01001000, the set {0, 2, 5}

    // for all shifts, the right operand (shift distance) must be unsigned.
    z := 1
    d := 1
    rotL := z<<uint8(d) | z>>uint8(7-d)
    rotR := z>>uint8(d) | z<<uint8(7-d)
    fmt.Println("-----")
    fmt.Printf("z =\t\t%08b\n", z)
    fmt.Printf("rotate Left =\t%08b\n", rotL)
    fmt.Printf("rotate Right =\t%08b\n", rotR)
    fmt.Println("-----")
}

/* Expected Output:
x =        01001010
y =        00000110
-----
x&y =  00000010    the intersection: AND
x|y =  01001110    the union: OR
x^y =  01001100    the symmetric difference: XOR
x&^y = 01001000    the difference: NOT
-----
members of x that are not 0
x =        01001010
1
3
6
-----
x is = 01001010
x<<1 =   10010100
x>>1 =   00100101
-----
z =        00000001
rotate Left =  00000010
rotate Right = 01000000
-----
*/



Comments