This week's book giveaway is in the Cloud/Virtualization forum.We're giving away four copies of Building Blockchain Apps and have Michael Yuan on-line!See this thread for details.
Win a copy of Building Blockchain Apps this week in the Cloud/Virtualization forum!
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
• Campbell Ritchie
• Paul Clapham
• Liutauras Vilda
• Knute Snortum
• Bear Bibeault
Sheriffs:
• Devaka Cooray
• Jeanne Boyarsky
• Junilu Lacar
Saloon Keepers:
• Ron McLeod
• Stephan van Hulst
• Tim Moores
• Carey Brown
• salvin francis
Bartenders:
• Tim Holloway
• Piet Souris
• Frits Walraven

# Operator Precedence

Greenhorn
Posts: 22
1
Hi,

In page 143 - 144 of the Jeanne Boyarsky's OCA certification book the following problem is there :-

Followed by the following explanation :-

"First, the x is incremented and returned to the expression, which is multiplied by 5. We can simplify this:

int y = 4 * 5 / x-- + --x; // x assigned value of 4

Next, x is decremented, but the original value of 4 is used in the expression, leading to this:

int y = 4 * 5 / 4 + --x; // x assigned value of 3

The final assignment of x reduces the value to 2, and since this is a pre-increment operator, that value is returned to the expression:

int y = 4 * 5 / 4 + 2; // x assigned value of 2

Finally, we evaluate the multiple and division from left-to-right, and finish with the addition. The result is then printed:

x is 2
y is 7"

I arrived at the same values of x and y but the approach is different ! My logic is since the post unary operators have the highest priority they will evaluated first, followed pre unary operators and then the binary operators. Hence, we will have y = (++x * 5 / 3 + --x) and x is now 2. Next, since now we have two unary operators (++x and --x) in midst of binary operators they will be evaluated from left to right. So we have, y = (3 * 5 / 3 + --x) with x = 3. Next, we have y = 3 * 5 / 3 + 2. So, finally x = 2 and 7.

author
Posts: 23868
141

Prabir Sarkar wrote:

Operator precedence and Order of evaluation are *not* the same thing -- nor is there a tight relationship, as you suggest here. Perhaps it would be a good idea to try out a different example, as one example, doesn't prove your approach is correct.

Henry

Prabir Sarkar
Greenhorn
Posts: 22
1
Quoting directly from the book (page 134) :-

"Java operators are not necessarily evaluated from left-to-right order. For example, the following Java expression is actually evaluated from right-to-left given the specific operators involved:

int y = 4;
double x = 3 + 2 * --y;

Unless overridden with parentheses, Java operators follow order of operation, (listed in Table 2.1), by decreasing order of operator precedence. If two operators have the same level of precedence, then Java guarantees left-to-right evaluation.

This makes sense to me. Now, in light of this, the explanation to evaluation of the problem that I posted doesn't match the above text.

Saloon Keeper
Posts: 11488
247
Then this is a mistake in the book. Java always evaluates expressions from left to right.

Ranch Hand
Posts: 231
12

Stephan, Roel and Henry expertly explain left to right evaluation here.

Prabir Sarkar
Greenhorn
Posts: 22
1

Thanks Daniel. If I understood that post correctly it says Java evaluates from left to right.

Prabir Sarkar
Greenhorn
Posts: 22
1
I also found this https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.7 which talks about left to right operations.

Marshal
Posts: 7501
509
• 2
When it gets confusing (evaluation order, precedence stuff, parentheses overriding something...), I tend to look for other words to describe what is happening, hopefully simpler.

What you do when you see such "tricky" questions, is, you go from left to right (always) and look for next operator in order to decide, either you need to calculate current value right with next variable's value or with a result of further (let's say 2nd and 3rd) variables calculation result.

Note: any further increments, decrements of variable doesn't affect your current variable value at hand.

Demonstrating (yours example) :
int x = 3;
int y = ++x * 5 / x-- + --x;

1. So, your x is 3. First operation is ++x. Increment first and place into expression (if were x++ then you'd put 3 into expression and would increment after that).
int y = 4 * 5 / x-- + --x;

2. You know that multiplication and division operators have same precedence, so you group your next operator right with next value, so you have:
int y = 4 * 5 / x-- + --x;

If division let assume had higher precedence than multiplication, then your next operation would have been (4 * result of 5 divided by x)
int y = 4 * (5 / x--) + --x;

This is what the operator's precedence does - decides which operands supposed to be grouped with which reading from left to right.

Ok, so you have now 4 * 5 = 20
int y = 20 / x-- + --x;

3. Next division, because division has higher precedence than plus. Now your x is 4. So, since it is post-decrement, you place current value into expression and only then decrement. So you have:
int y = 20 / x-- + --x;
int y = 20 / 4 + --x;
int y = 5 + --x;

4. Next. Last one. Your x got decremented from 4 to 3 from previous step, and now you have pre-decrement, so it becomes 2.
int y = 5 + --x;
int y = 5 + 2;
int y = 7

Liutauras Vilda
Marshal
Posts: 7501
509
• 1

Earlier, I wrote:Note: any further increments, decrements of variable doesn't affect your current variable value at hand.

I need to emphasize what I meant here.

Consider this:
int x = 2;
int y = x + (++x - ++x);

Now, you see that you have parentheses, but once again, since evaluation happens from left to right, it doesn't affect your very first x value at hand. So if I put values, the expression would look:
int y = 2 + (++x - ++x)
int y = 2 + (3 - ++x)
int y = 2 + (3 - 4)

If Java were let's say not left to right, expression might would end up with:
int y = x + (3 - ++x)
int y = x + (3 - 4)
int y = 4 + (3 - 4)

Prabir Sarkar
Greenhorn
Posts: 22
1
That is incredibly nice and details. Thanks much for your help and guidance Liutauras Vilda!

Daniel Cox
Ranch Hand
Posts: 231
12
• 1

Prabir Sarkar wrote:I also found this https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.7 which talks about left to right operations.

The exact quote is

The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.

which means that the operands in the expression
will be evaluated from left to right as follows:

1. y will be evaluated first

JLS
First, the left-hand operand is evaluated to produce a variable.

2. Next, x will be evaluated, followed by 5, followed by x, followed by x

Stephan van Hulst
Saloon Keeper
Posts: 11488
247
• 3
This is not just important for variables, but also method calls with side-effects:

This program will print:

So it's clear the expression is evaluated from left to right, even though * has a higher precedence than + .

Liutauras Vilda
Marshal
Posts: 7501
509
That's it! Smashing example. Never thought of it.

Daniel Cox
Ranch Hand
Posts: 231
12

Stephan van Hulst wrote:

Prabir Sarkar wrote:
Quoting directly from the book (page 134) :-

"Java operators are not necessarily evaluated from left-to-right order. For example, the following Java expression is actually evaluated from right-to-left given the specific operators involved:

int y = 4;
double x = 3 + 2 * --y;

Then this is a mistake in the book. Java always evaluates expressions from left to right.

I don't think that the book is mistaken since it is talking about evaluation of operators in an expression, not evaluation of operands in an expression.

Evaluation of operators in an expression is based on operator precedence (and parentheses).

JLS
The Java programming language respects the order of evaluation indicated explicitly by parentheses and implicitly by operator precedence.

Evaluation of operands in an expression is always left to right.

JLS
The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.

Liutauras Vilda
Marshal
Posts: 7501
509

Daniel Cox wrote:I don't think that the book is mistaken since it is talking about evaluation of operators in an expression, not evaluation of operands in an expression.

You are right. I think most people misread that part. Have a cow for error fix.

Stephan van Hulst
Saloon Keeper
Posts: 11488
247
The language is confusing though. What it means is that "operands are not necessarily bound to operators from left to right", or "operators are not necessarily left-associative". Resolving operator precedence is done by the compiler, and nothing is evaluated.

Sheriff
Posts: 11604
178

Liutauras Vilda wrote:That's it! Smashing example. Never thought of it.

And I thought you were a big fan of my posts

Roel De Nijs
Sheriff
Posts: 11604
178

That's really a very common question (confusion) on this forum! You should definitely read this topic and this one as both topics provide excellent explanations (with illustrative code snippets) about the same code snippet. And if you want to learn more about the order of evaluation of (post-)increment (& decrement) operators, this topic is also definitely worth reading. And if you want to learn more about evaluating boolean expressions with short-circuit operators this topic and this one are must-read topics.

Hope it helps!
Kind regards,
Roel

Liutauras Vilda
Marshal
Posts: 7501
509
Prabir Sarkar,

Cowgratulations, your topic has been published in August edition of our CodeRanch Journal.

Prabir Sarkar
Greenhorn
Posts: 22
1
I am indeed honored by all the posts that helped to enrich the topic of discussion. This Cowgratulation belongs to ALL who contributed to this post. Thanks again!

 What's wrong? Where are you going? Stop! Read this tiny ad: Java file APIs (DOC, XLS, PDF, and many more) https://products.aspose.com/total/java