Search code examples
gotypesbit-shift

Discrepancy in Bitwise Shift Calculation Results


I'm encountering a discrepancy in the output of my Go program, specifically with the variables x1 and x2. Here's the relevant code snippet:

package main

var n uint = 10
const N uint = 10

func main() {
    var x1 byte = (1 << n) / 100
    var x2 byte = (1 << N) / 100
    println(x1, x2)
}

Expected output: 10 10

Actual Output: 0 10

Curious about the reasoning behind the difference, seeking explanation.


Solution

  • Constant expressions get evaluated with unspecified precision. Everything in the assignment to x2 is constant so it's properly calculating 210 / 100 = 1024 / 100 = 10. Whereas in the first expression the 1 is treated as a byte, meaning it just gets shifted out immediately. That the 1 must get treated as a byte is in the spec:

    If the left operand of a non-constant shift expression is an untyped constant, it is first implicitly converted to the type it would assume if the shift expression were replaced by its left operand alone.

    1 is the untyped constant on the left here, and n being var makes the expression non-constant, so that 1 has to have the type of its assignee x1, i.e. byte.