Tuesday, 26 October 2010

Operator Precedence

Precedence determines order of evaluation

Mathematical tradition, which programming languages generally try to match, dictates that some operations are done before others (for example, multiplication and division are done before addition and subtraction).

a+b*c is the same as a+(b*c), not (a+b)*c.

Ever operator has a precedence (a number) associated with it. The precedence determines which operations will be performed first. Multiplication has higher precedence than addition, as illustrated in the previous example..

Equal precedence operations generally performed left-to-right

In addition to the precedence of each operator, the compiler also knows whether equal-precedence operators should be performed left-to-right (almost all) or right-to-left (basically only assignment).

Parentheses can be used to control the order of evaluation

If you have any doubt about the order of evaluation, or have a potentially confusing expression, use parentheses. Remember that one of your goals should be to make your programs as readable as possible. Use parentheses when it makes an expression easier to read, not must when they are absolutely required. Few programmers know the precedence of all operators, so it's common for extra parentheses to be used.

Unary (one operand) versus binary (two operand) operators

Unary operators have only one operand, for example, in

   a = -b;

The "-" operator is the unary (one operand) operator which changes the sign of its operand.

   a = b - c

The "-" operator is a binary (two operand) operator which subtracts c from b.

Most unary operators are performed before binary operators (exceptions "." (qualification), "[]" (subscription), and "()" (method call).

Example - Parentheses


When you can work out the precedence, it's often useful to use parentheses to figure out the order of evaluation. For example, let's say you're evaluating the following expression.

 1 + 2 - 3 * 4 / 5

Addition and subtraction are equal in precedence and lower than multiplication and division, which are equal. Form the parenthesized form and work out the values in steps.


  1. 1 + 2 - 3 * 4 / 5
  2. = (1 + 2) - ((3 * 4) / 5)
  3. = 3 - (12/5)
  4. = 3 - 2 The result of the integer division, 12/5, is 2 .
  5. = 1

Precedence table


This table gives the precedence of all operators. You may not be familiar with all operators, but take the advice on the right side and only learn a few precedences.

Operator Precedence

. [] (args) post ++ --
! ~ unary + - pre ++ --
(type) new
* / %
+ -
<< >> >>>
< <= > >= instanceof
== !=
&
^
|
&&
||
?:
= += -= etc

Remember only

  1. unary operators
  2. * / %
  3. + -
  4. comparisons
  5. && ||
  6. = assignments
Use () for all others

Alternative notation - Dataflow diagram


Let's look at the expression x = a+b-c*d/e, which can be parenthesized as x = ((a+b) - ((c*d)/e)). Instead of parentheses, we can draw a diagram.

dataflow-tree
This dataflow diagram shows another way to think about expression evaluation.

Boxes represent values in memory, ovals represent operations, and arrows show the direction of data flow. The assignment operator ("=") is treated as an operator with low precedence by the compiler, but from a dataflow point of view it only moves data so it's represented as an arrow, not an operation.

Dataflow diagrams show which operations must necessarily be performed before others, but doesn't show which are actually performed first. Java performs most operations left-to-right, so the addition would, in principle, be performed before the multiplication. I believe reordering of operations that can have no side effects is allowed, however.

Alternative notation - Postfix - RPN


Postfix. Altho it's not directly relevant to learning Java, there are other systems for writing expressions that don't need parentheses or precedence. Normal mathematical notation is called infix notation because the operators occur in between the operands. A common alternative is called postfix notation where the operator is written after its two operands.

Example. For example, a+b would be written as ab+ , and x = a+b-c*d/e would be written as xab+cd*e/-=.

RPN. This is often called Reverse Polish Notation in honor of the Polish mathematician Jan Lukasiewicz.

Postfix notation is used in the following, among others.


  • Hewlett-Packard makes RPN calculators.
  • The Postscript printer control language is postfix.
  • The Forth programming language is RPN.
  • Java source code is translated into postfix notation!

No comments:

Post a Comment