• Post Reply Bookmark Topic Watch Topic
  • New Topic

Operator Precedence  RSS feed

 
Prabir Sarkar
Greenhorn
Posts: 22
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
   I am some problem this operator precedence problem. Please help.

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.

Please help me with understanding which is the correct approach. Thanks in advance. 
 
Henry Wong
author
Sheriff
Posts: 23292
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prabir Sarkar wrote:
Please help me with understanding which is the correct approach. Thanks in advance. 


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
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Stephan van Hulst
Saloon Keeper
Posts: 7932
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Then this is a mistake in the book. Java always evaluates expressions from left to right.
 
Daniel Cox
Ranch Hand
Posts: 231
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prabir Sarkar wrote:Please help me with understanding which is the correct approach. Thanks in advance. 

Stephan, Roel and Henry expertly explain left to right evaluation here.
 
Prabir Sarkar
Greenhorn
Posts: 22
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Thanks Daniel. If I understood that post correctly it says Java evaluates from left to right.
 
Prabir Sarkar
Greenhorn
Posts: 22
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Liutauras Vilda
Marshal
Posts: 4827
330
BSD
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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: 4827
330
BSD
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That is incredibly nice and details. Thanks much for your help and guidance Liutauras Vilda!
 
Daniel Cox
Ranch Hand
Posts: 231
12
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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: 7932
143
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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: 4827
330
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's it! Smashing example. Never thought of it.
 
Daniel Cox
Ranch Hand
Posts: 231
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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: 4827
330
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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: 7932
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Roel De Nijs
Sheriff
Posts: 11338
177
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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: 11338
177
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prabir Sarkar wrote:I am some problem this operator precedence problem. Please help.

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: 4827
330
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prabir Sarkar,

Cowgratulations, your topic has been published in August edition of our CodeRanch Journal.
 
Prabir Sarkar
Greenhorn
Posts: 22
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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!
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!