A = (a ++) * (a ++) gives weird results in Java

I am studying the OCPJP exam and therefore I have to understand every little weird detail of Java. This includes the order in which the pre and post-increment statements are applied to variables. The following code gives me weird results:

int a = 3; a = (a++) * (a++); System.out.println(a); // 12 

Shouldn't there be an answer? Or maybe 13? But not 12!

SUBSEQUENT:

What is the result of the following code?

 int a = 3; a += (a++) * (a++); System.out.println(a); 
+45
java order-of-evaluation operator-precedence post-increment ocpjp
Nov 07 '11 at 16:00
source share
15 answers

After the first a++ a becomes 4. Thus, you have 3 * 4 = 12 .

( a becomes 5 after the second a++ , but this is discarded because assigning a = cancels it)

+110
Nov 07 2018-11-11T00:
source share

Your expression:

 a += (a++) * (a++); 

equivalent to any of them:

 a = a*a + 2*a a = a*(a+2) a += a*(a+1) 

Use any of them.

+31
Nov 07 2018-11-11T00:
source share

a++ means "the value of a, and a then increases by 1". Therefore when you run

 (a++) * (a++) 

first, the first a++ is evaluated and returns a value of 3. a then incremented by 1. Then the second a++ calculated. a displays the value 4 and then increments again (but now it doesn't matter)

So it turns into

 a = 3 * 4 

which is 12.

+25
Nov 07 2018-11-11T00:
source share
 int a = 3; a += (a++) * (a++); 

First, build a syntax tree:

 += a * a++ a++ 

To appreciate this, start with the outer elementary element and the descent recursively. For each do element:

  • Rate children from left to right
  • Rate the item itself

The += operator is special: it expands to the value left = left + right , but only evaluates the left expression once. However, the left side is evaluated as a value (and not just a variable) before the right side is evaluated to a value.

It leads to:

  • Start evaluating +=
  • Evaluate the left side of variable assignment a .
  • Rate variable a value of 3 , which will be used in the appendix.
  • Start assessment *
  • Rate the first a++ . This returns the current value of a 3 and sets a to 4
  • Rate the second a++ . This returns the current value of a 4 and sets a to 5
  • Calculate the product: 3 * 4 = 12
  • Run += . The left side was rated at 3 in the third step, and the right side was 12 . Therefore, he assigns 3 + 12 = 15 to a .
  • The final value of a is 15.

It should be noted here that the priority of the operator does not directly affect the evaluation procedure. This affects only the shape of the tree and, therefore, indirectly on the order. But among the siblings in the tree, the score is always from left to right, regardless of the priority of the operator.

+9
Nov 08 '11 at 11:20
source share

(a++) is an increment, so the value of the expression is 3.

(a++) is an increment, so the value of the expression is now 4.

Evaluation of expressions occurs from left to right.

 3 * 4 = 12 
+7
Nov 07 2018-11-11T00:
source share

Each time you use ++, you add post-incrementing a. This means that the first a ++ evaluates to 3, and the second evaluates to 4. 3 * 4 = 12.

+7
Nov 07 2018-11-11T00:
source share

There is a general lack of understanding of how operators work. Honestly, every statement is syntactic sugar.

All you have to do is understand what is actually happening for each operator. Assume the following:

 a = b -> Operators.set(a, b) //don't forget this returns b a + b -> Operators.add(a, b) a - b -> Operators.subtract(a, b) a * b -> Operators.multiply(a, b) a / b -> Operators.divide(a, b) 

Complex operators can then be rewritten using these generalizations (please ignore return types for simplicity):

 Operators.addTo(a, b) { //a += b return Operators.set(a, Operators.add(a, b)); } Operators.preIncrement(a) { //++a return Operators.addTo(a, 1); } Operators.postIncrement(a) { //a++ Operators.set(b, a); Operators.addTo(a, 1); return b; } 

You can rewrite your example:

 int a = 3; a = (a++) * (a++); 

but

 Operators.set(a, 3) Operators.set(a, Operators.multiply(Operators.postIncrement(a), Operators.postIncrement(a))); 

What can be divided using several variables:

 Operators.set(a, 3) Operators.set(b, Operators.postIncrement(a)) Operators.set(c, Operators.postIncrement(a)) Operators.set(a, Operators.multiply(b, c)) 

This, of course, in more detail, but it immediately becomes obvious that you never want to perform more than two operations on the same line.

+5
Nov 07 '11 at 19:05
source share

When:

 int a = 3; a = (a++) * (a++); a = 3 * a++; now a is 4 because of post increment a = 3 * 4; now a is 5 because of second post increment a = 12; value of 5 is overwritten with 3*4 ie 12 

therefore, we get the output as 12.

When:

 a += (a++) * (a++); a = a + (a++) * (a++); a = 3 + (a++) * (a++); // a is 3 a = 3 + 3 * (a++); //a is 4 a = 3 + 3 * 4; //a is 5 a = 15 



The main thing to note here is that in this case the compiler decides from left to right and in the case of incremental increments, the value up to the increment is used in the calculation, and when moving from left to right, the incremented value is used.

+5
Nov 09 2018-11-11T00:
source share

(a++) means return a and increment, so (a++) * (a++) means 3 * 4

+3
Nov 07 '11 at 16:05
source share

Here is the java code:

 int a = 3; a = (a++)*(a++); 

Here is the bytecode:

  0 iconst_3 1 istore_1 [a] 2 iload_1 [a] 3 iinc 1 1 [a] 6 iload_1 [a] 7 iinc 1 1 [a] 10 imul 11 istore_1 [a] 

Here's what happens:

Inserts 3 onto the stack, then pops 3 from the stack and saves it at a point. Now a = 3, and the stack is empty.

  0 iconst_3 1 istore_1 a 

Now it pushes the value from "a" (3) onto the stack and then increments (3 β†’ 4).

  2 iload_1 [a] 3 iinc 1 1 [a] 

So now "a" is "4", the stack is {3}.

Then it reloads "a" (4), pushes it onto the stack, and increments "a".

  6 iload_1 [a] 7 iinc 1 1 [a] 

Now "a" is 5, and the stack is {4.3}

Thus, it finally pushes two values ​​from the stack (4 and 3), multiplies and saves it back to the stack (12).

  10 imul 

Now "a" is 5, and the stack is 12.

Finally, pops 12 from the stack and saves in.

  11 istore_1 [a] 

TADA!

+3
Nov 08 '11 at 18:39
source share

This is 12. The expression begins to be evaluated on the left. So it does:

 a = (3++) * (4++); 

After calculating the first part (3 ++), a is 4, so in the next part it does a = 3 * 4 = 12. Note that the last post-increment (4 ++) is executed, but has no effect, because after that it is assigned the value 12.

+2
Nov 07 2018-11-11T00:
source share

Example 1

 int a = 3; a = (++a) * (a++); System.out.println(a); // 16 

Example 2

 int a = 3; a = (++a) * (++a); System.out.println(a); // 20 

Just to make sure where to put a ++ expression that changes the value based on location.

+1
Nov 08 '11 at 17:09
source share

Each clearly explained the first expression and why the value of a is 12.

To answer the question, the answer is absolutely obvious to the casual observer:

17

+1
Nov 08 '11 at
source share

If you use ++, then the next time you use a, it increases by one. So you do

 a = 3 * (3 + 1) = 3 * 4 = 12 
0
Nov 07 2018-11-11T00:
source share

The pre and post-prefix increments take precedence over the multiplication operator. therefore, the expression evaluates to 3 * 4.

0
Nov 07 '11 at 16:08
source share



All Articles