Search code examples
gooperator-precedence

Bitshift << and multiplication * precedence


Tried this code on Go playground:

package main

import (
    "fmt"
)

func main() {
    log2Dim := uint32(9)
    
    SIZE := 1 << 3 * log2Dim
    fmt.Printf("Result: %v\n", SIZE)
    
    SIZE = 1 << (3 * log2Dim)            // => only difference: adding ( )
    fmt.Printf("Result: %v\n", SIZE)
}

This is printed out:

Result: 72
Result: 134217728

Why does it make a huge difference just adding ( ) to the statement containing << and * operations?

According to this, * has higher precedence over <<, which is Google first result searching for bitshift precedence golang.


Solution

  • The page you linked to is wrong. There is only one spec for Go and it's pretty clear about operator precedence:

    There are five precedence levels for binary operators. Multiplication operators bind strongest, followed by addition operators, comparison operators, && (logical AND), and finally || (logical OR):

        5             *  /  %  <<  >>  &  &^
        4             +  -  |  ^
        3             ==  !=  <  <=  >  >=
        2             &&
        1             ||
    

    Binary operators of the same precedence associate from left to right. For instance, x / y * z is the same as (x / y) * z.

    Multiplication and bitshift are at the same precedence level so the "left to right" rule applies, making your code the equivalent of (1 << 3) * log2Dim

    Note that left to right means in the code, not in the precedence table. This is seen by the example given in the spec.