Prabir Sarkar

Greenhorn

Posts: 22

1

posted 3 months ago

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.

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.

posted 3 months ago

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 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

posted 2 months ago

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.

"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

Daniel Cox

Ranch Hand

Posts: 231

12

posted 2 months ago

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

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

Prabir Sarkar

Greenhorn

Posts: 22

1

posted 2 months ago

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.

posted 2 months ago

- 1

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) :

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).

2. You know that multiplication and division operators have same precedence, so you group your next operator right with next value, so you have:

If division let assume had higher precedence than multiplication, then your next operation would have been (4 *

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

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:

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.

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;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`
posted 2 months ago

I need to emphasize what I meant here.

Consider this:

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:

If Java were let's say not left to right, expression might would end up with:

- 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);

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

Daniel Cox

Ranch Hand

Posts: 231

12

posted 2 months ago

The exact quote is

which means that the operands in the expression

will be evaluated from left to right as follows:

1.

2. Next,

- 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: 7932

143

posted 2 months ago

- 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

This program will print:

So it's clear the expression is evaluated from left to right, even though

`*`has a higher precedence than`+`.*The mind is a strange and wonderful thing. I'm not sure that it will ever be able to figure itself out, everything else, maybe. From the atom to the universe, everything, except itself.*

Daniel Cox

Ranch Hand

Posts: 231

12

posted 2 months ago

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).

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

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.

posted 2 months ago

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

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

posted 2 months ago

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.

posted 2 months ago

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

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