Operator precedence

January 26, 2024

I hope we all know what operator precedence means… but just in case it’s fuzzy, I’ll illustrate with a simple example from junior high school.

What does this mean?

1 + 2 * 3

It’s either 9 or 7, right?

It depends on the order in which we apply the + and * operations.

I’m sure most of us agree that the correct answer is actually 7, because multiplication takes precedence over addition. That is to say, the proper steps to solving this equation are to first multiply 2 * 3, leaving us with 1 + 6, then do the addition.

If we want the answer 9, we can specify this by using parenthesis:

(1 + 2) * 3

Now we do the 1 + 2 addition first, leaving 3 * 3, which we then solve to 9.

Go has the same concept, and below are the rules for which operators take precedence when:

Operator precedence

Unary operators have the highest precedence. As the ++ and -- operators form statements, not expressions, they fall outside the operator hierarchy. As a consequence, statement *p++ is the same as (*p)++.

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

Precedence    Operator
    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.

+x
23 + 3*x[i]
x <= f()
^a >> b
f() || g()
x == y+1 && <-chanInt > 0

Quotes from The Go Programming Language Specification Version of August 2, 2023


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content


Operators

Operators Operators combine operands into expressions. Nice. I love a concise description/definition. Especially after the confusion that was yesterday’s post about loose and exact unification. Expression = UnaryExpr | Expression binary_op Expression . UnaryExpr = PrimaryExpr | unary_op UnaryExpr . binary_op = "||" | "&&" | rel_op | add_op | mul_op . rel_op = "==" | "!=" | "<" | "<=" | ">" | ">=" . add_op = "+" | "-" | "|" | "^" .


Floating-point operators

Floating-point operators For floating-point and complex numbers, +x is the same as x, while -x is the negation of x. The result of a floating-point or complex division by zero is not specified beyond the IEEE-754 standard; whether a run-time panic occurs is implementation-specific. I find this to be quite interesting. An implementation may choose to panic, or not, if you attempt to divide a floating-point or complex number by zero.


Arithmetic operators

Arithmetic operators Arithmetic operators apply to numeric values and yield a result of the same type as the first operand. The four standard arithmetic operators (+, -, *, /) apply to integer, floating-point, and complex types; + also applies to strings. The bitwise logical and shift operators apply to integers only. + sum integers, floats, complex values, strings - difference integers, floats, complex values * product integers, floats, complex values / quotient integers, floats, complex values % remainder integers & bitwise AND integers | bitwise OR integers ^ bitwise XOR integers &^ bit clear (AND NOT) integers << left shift integer << integer >= 0 >> right shift integer >> integer >= 0 There should be nothing surprising here.