What precedence is
When an expression contains several operators, Scala has to decide which one to apply first. The rules for that decision are called operator precedence. They are the same rules as in school arithmetic, so most results will look familiar:
println(1 + 2 * 3)
println(6 - 4 / 2)
println(5 * 4 - 2 / 2)
7
4
19
In 1 + 2 * 3, the multiplication runs first, so the expression is 1 + 6, which is 7. Without precedence rules it would be ambiguous whether the answer is 7 or 9.
The rules
From highest to lowest, for the operators in this chapter:
- Parentheses
( ): whatever is inside runs first. *,/and%: multiplication, division and remainder share one rank.+and-: addition and subtraction share the next rank.
Within a single rank, Scala works from left to right. Scala has no power operator, so there is no exponent level. To raise a number to a power, call math.pow(2, 3), which returns the Double value 8.0.
Forcing an order with parentheses
Parentheses override the default order. Every example below uses the numbers of the first group, but in a different grouping:
println((1 + 2) * 3)
println((6 - 4) / 2)
println(5 * (4 - 2) / 2)
9
1
5
In (1 + 2) * 3 the addition is computed first, giving 3 * 3. Parentheses can also be nested. Scala evaluates the innermost pair first:
println(6 / ((4 + 2) / 3))
3
The steps are: 4 + 2 is 6, then 6 / 3 is 2, then 6 / 2 is 3.
Equal rank and integer division
Because * and / share a rank, 6 / 4 * 3 + 5 is evaluated as ((6 / 4) * 3) + 5. With Int numbers, 6 / 4 is 1 (the fraction is dropped), then 1 * 3 is 3, then 3 + 5 is 8:
println(6 / 4 * 3 + 5)
println(6.0 / 4 * 3 + 5)
8
9.5
Only when one operand is a Double does 6.0 / 4 become 1.5 and the whole expression gives 9.5. The remainder operator belongs to the same rank, so 1 + 2 % 3 * 4 is 1 + ((2 % 3) * 4), which is 9.
The exercise
The starter code prints the value of 2 + 3 * 3. Multiplication wins, so Scala computes 3 * 3 = 9 and then adds 2, printing 11. The goal is an output of 15.
Ask which sum, multiplied by 3, gives 15. It is 5, and 5 is 2 + 3. So the addition has to run first, and that means putting it in parentheses:
println((2 + 3) * 3)
Now the program computes 5 * 3 and prints 15. The numbers and operators are the same as before. Only the grouping changed.
Common mistakes
- Reading left to right only. A reader scanning
2 + 3 * 3from left to right may expect 15. Scala gives 11. - Parentheses around the wrong part.
2 + (3 * 3)still gives 11, because it only makes the default order explicit. - Unbalanced parentheses. Each
(needs a matching), including the one that closesprintln(. - Trusting integer division order.
5 / 2 * 4is 8, while5 * 4 / 2is 10.
When in doubt, add parentheses. They never change the result when they match the default order, and they make the code easier to read.
Key takeaways
*,/and%run before+and-.- Operators of the same rank run from left to right.
- Parentheses always run first, innermost first.
- Scala has no power operator; use
math.pow.
