int a = 6;
int b = 5;
System.out.print(a *= a++ - (a++) * b);
result out -174
I thought (a++) -> 6
and following the operation ordering, 7 - (6) * 5 => -23
then a should be now 8.
so 8 *= -23 => -184 is what I thought
Please help me out step by step which was wrong and I misunderstand.
Thanks
According to the Java Language Specification section 15.7.1,
The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.
So in your case, the unparenthesised a++ is evaluated before (a++) * b, which makes the right hand side of the assignment equal to 6 - 7 * 5. That's equal to -29, and multiplying a by -29 gives -174.
Related
public static void main(String[] args) {
int A=5;
int B=2;
A *= B*= A *= B ;
System.out.println(A);
System.out.println(B);
}
When I calculated this problem on paper I found A=200 B=20, but when I write it down to eclipse it shows A=100 B=20
Can you explain the solution like solving on the paper?
I tried to solve in Eclipse and by myself.
How do we solve it?
Starting off with A=5, B=2
A becomes A * B * A * B, which is 100, and
B becomes B * A * B, which is 20.
In more detail:
A *= B *= A *= B
is
A = A * (B = B * (A = A * B))
That resolves to
A = 5 * (B = 2 * (A = 5 * 2))
which means
A = 5 * (B = 2 * (A = 10)) // set A to 10
A = 5 * (B = 2 * 10)
A = 5 * (B = 20) // set B to 20
A = 5 * 20
A = 100 // set A to 100
This has to do with evaluation of operands taking place before order of operators (precedence).
Before operators are executed, the operands are evaluated, which in Java always take place in a left-to-right order.
The leftmost A is evaluated as 5, then the leftmost B is 2, then the second A is 5 and the second B is also 2. These values are saved for later computation.
The JLS, Section 15.26.2, deals with the procedure of evaluating a compound assignment operator.
If the left-hand operand expression is not an array access expression, then:
First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs.
Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.
(bold emphasis mine)
Then the operators are executed, with *= having right-associativity. This means that operation proceeds right-to-left. The rightmost A *= B is executed, assigning 10 to A. The the middle B *= A is executed, assigning 20 to B. However, when the leftmost A *= B is executed, the saved value of A is still there -- 5. When multiplied by 20, 100 is assigned to A.
A *= B*= A *= B; // A is now 100
If we break this up into 3 statements, then you will get the expected 200, because A will be evaluated again as part of the last statement as 10, not 5, because the saved value for A is now 10.
A *= B;
B *= A;
A *= B; // A is now 200
I'm a little confused about the result of the following code:
int x = 1;
x -= ((x += 1) << 1);
System.out.println(x);
It prints out -3, but I'd expected it to print out -2, because in my head the computation should go like this:
| Opearation | Returned | x |
+------------+----------+---+
| int x = 1; | - | 1 |
+------------+----------+---+
| (x += 1) | 2 | 2 |
+------------+----------+---+
| (2 << 1) | 4 | 2 |
+------------+----------+---+
| x -= 4; | - |-2 |
What am I missing here? Can somebody please explain to me what's going on?
Thanks!
JLS 15.26.2 says following, https://docs.oracle.com/javase/specs/jls/se9/html/jls-15.html#jls-15.26.2
If the left-hand operand expression is not an array access expression, then:
First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs.
Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.
So the original value of x, i.e. 1, is saved, then the RHS is evaluated. Therefore it's -3.
Unlike some other languages (looking at you, C++), the Java Language Specification guarantees that expression operands are evaluated left-to-right:
The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.
Let's unroll your compound statement:
x -= ((x += 1) << 1);
x = x - ((x = x + 1) << 1);
^
The x with the arrow is evaluated first, which means that the assignment that happens later within the expression doesn't affect the value (in this case, the JVM stack already has a 1 on it). The rest of the evaluation proceeds as you expect, but the final operation is 1 - 4 = -3.
Note that right after the statement above, the JLS also includes a note that absolutely applies here:
It is recommended that code not rely crucially on this specification. Code is usually clearer when each expression contains at most one side effect, as its outermost operation, and when code does not depend on exactly which exception arises as a consequence of the left-to-right evaluation of expressions.
Value of x (=1) is populated on the RHS of the expression before the sub-expression (x+=1) is processed hence leftmost x is substituted as 1 way before it is processed in x+=1 which results into 2. Hence it will be ...
x = 1 - ((x=1+1) << 1)
x = 1 - ((x=2) << 1)
x = 1 - (2 << 1)
x = 1 - 4
x = -3
Here x=2 results into 2 as assignment operator returns same value as assigned to the variable.
x -= ((x += 1) << 1);
x = x - ((x += 1) << 1);
= 1 - ((1 + 1) << 1);
= 1 - (2 << 1)
= 1 - 4
= -3
I am wondering with post and pre increment and decrement operation.
what I know in Java precedence of post operator is high and associativity is left-to-right.while associativity of pre operator is right-to-left
Oracle Java Tutorial
but my code showing me undesired result-
public class Bunnies {
static int count = 3;
public static void main(String[] args) {
System.out.println(--count*count++*count++);//out put is 12 expected 48
//associativity of post is higher so should be evaluated like this-
//--count*3**count++ count is 4 now
//--count*3*4 count is 5 now
//4*3*4=48
count = 3;
System.out.println(--count*++count*++count); //out put is 24 expected 120
//associativity of pre is right to left so should be evaluated like this-
//--count*++count*4 count is 4 now
//--count*5*4 count is 5 now
//4*5*4=120
count = 3;
System.out.println(-- count*count++);// out put is 4 expected 9
//--count*3 count is 4 now
//3*3=9
}
}
Order of evaluation of subexpressions is independent of both associativity and precedence.
The subexpression of the multiplication are evaluated from left to right, so when doing --count*count++*count++, you evaluate --count then count++ and finally count++.
And as the pre operator is evaluated first, --count will be decremented before its evaluation. In the same way, as the post operator is evaluated lately, count++ will be incremented after its evaluation.
The precedence only help the compiler to create a correct abstract syntactic tree.
For example, when doing ++count*2, the compiler use the precedence to know the expression is (++count)*2 and not ++(count*2). In the same way, when doing ++count*count--, the expression is (++count)*(count--) and not (++(count * count))-- or whatever. But then, during the evaluation of the multiplication ++count is evaluated before count--.
Hope this help you :)
I just found a great answer about expression evaluation in C# and Java here, enjoy :)
System.out.println(--count*count++*count++);
= 2 * 2 * 3 = 12
count = 3;
System.out.println(--count*++count*++count)
= 2*3*4 = 24
count = 3;
System.out.println(-- count*count++);
= 2 * 2 = 4
Pre increment/decrement
++/-- X first increments/decrements then does the operation.
Post increment/decrement
X ++/-- first the operation is done, then increment / decrement.
I take the first one.
System.out.println(--count*count++*count++);//out put is 12 expected 48
2 * 2 * 3 = 12
pre * post * post
count = 3:
Example 1:
--count*count++*count++ equals (--count)*(count++)*(count++)
(--count) = 2
(count++) = 2 (you increment it AFTER you do something with it)
(count++) = 3 ... count was incremented from before
2*2*3 = 12
Example 2:
--count*++count*++count equals (--count)*(++count)*(++count)
--count = 2
++count = 3
2 * 3 * 3 = 24
Example 3:
(--count)*(count++)
--count = 2
2 * 2 (the count++ gets changed afterwards)
Keep in mind that you have to watch the multiplicaton operator
This question already has answers here:
What are the rules for evaluation order in Java?
(5 answers)
If parenthesis has a higher precedence then why is increment operator solved first?
(5 answers)
Closed 7 years ago.
In this code:
int y = 10;
int z = (++y * (y++ + 5));
What I expected
First y++ + 5 will be executed because of the precedence of the innermost parentheses. So value of y will be 11 and the value of this expression will be 15. Then ++y * () will be executed. So 12 * 15 = 180. So z=180
What I got
z=176
This means that the VM is going from left to right not following operator precedence. So is my understanding of operator precedence wrong?
The expression (++y * (y++ + 5)); will be placed in a stack something like this:
1. [++y]
2. [operation: *]
3. [y++ + 5] // grouped because of the parenthesis
And it will be executed in that order, as result
1. 10+1 = [11] // y incremented
2. [operation: *]
3. 11+5 = [16] // y will only increment after this operation
The the expression is evaluated as
11 * 16 = 176
First y++ + 5 will be executed because of the precedence of the innermost parentheses
Precedence and evaluation order are not the same thing. All binary expressions except the assignment expression are evaluated left-to-right. Therefore y++ is evaluated before the parenthesized expression on the right.
The parentheses just describe how the sub-expressions will be grouped together. Parenthesizing doesn't mean it will be evaluated first. Rather, the rule in java is evaluate each sub-expression strictly from left to right.
Always remember that the order of evaluation has absolutely nothing to do with operator precedence and associativity.
Java Oracle documentation says that:
15.7. Evaluation Order
The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.
Therefore, the expression (++y * (y++ + 5)) will be evaluated as
temp1 = ++y = 11
temp2 = y++ + 5 = 11 + 5 = 16
z = temp1*temp2 = 11*16 = 176
Further reading: Eric Lippert's blog, Precedence vs Associativity vs Order, explained in detailed about precedence, associativity and order of evaluation. Though this blog addresses c# but equally valid for java too.
First will be executed ++y. y will be 11.
Then will be executed y + 5 (actually y++ + 5 can be written as 5 + y++ which is interpreted as (5 + y) and then y++). z will become 11 * 16 = 176.
y will be 12 after the calculation finishes.
The calculation is going on following order
z= (++10 * (10++ + 5))
z= (11 * (11 + 5))//++ (prefix or postfix) has higher precedence than + or *
z= (11 * 16)
z= 176
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I'm studying for the OCPJP exam, and so I have to understand every little strange detail of Java. This includes the order in which the pre- and post-increment operators apply to variables. The following code is giving me strange results:
int a = 3;
a = (a++) * (a++);
System.out.println(a); // 12
Shouldn't the answer be 11? Or maybe 13? But not 12!
FOLLOW UP:
What is the result of the following code?
int a = 3;
a += (a++) * (a++);
System.out.println(a);
After the first a++ a becomes 4. So you have 3 * 4 = 12.
(a becomes 5 after the 2nd a++, but that is discarded, because the assignment a = overrides it)
Your statement:
a += (a++) * (a++);
is equivalent to any of those:
a = a*a + 2*a
a = a*(a+2)
a += a*(a+1)
Use any of those instead.
a++ means 'the value of a, and a is then incremented by 1'. So when you run
(a++) * (a++)
the first a++ is evaluated first, and produces the value 3. a is then incremented by 1. The second a++ is then evaluated. a produces the value of 4, and is then incremented again (but this doesn't matter now)
So this turns into
a = 3 * 4
which equals 12.
int a = 3;
a += (a++) * (a++);
First build the syntax tree:
+=
a
*
a++
a++
To evaluate it start with the outer most element and descent recursively. For each element do:
Evaluate children from left to right
Evaluate the element itself
The += operator is special: It gets expanded to something like left = left + right, but only evaluating the expression left once. Still the left side gets evaluated to a value(and not just a variable) before the right side gets evaluated to a value.
This leads to:
Start evaluating +=
Evaluate left side of assignment to the variable a.
Evaluate the variable a to the value 3 which will be used in the addition.
Start evaluating *
Evaluate the first a++. This returns the current value of a 3 and sets a to 4
Evaluate the second a++. This returns the current value of a 4 and sets a to 5
Calculate the product: 3*4 = 12
Execute +=. The left side had been evaluated to 3 in the third step and the right side is 12. So it assigns 3+12=15 to a.
Final value of a is 15.
One thing to note here is that operator precedence has no direct influence on evaluation order. It only affects the form of the tree, and thus indirectly the order. But among siblings in the tree the evaluation is always left-to right, regardless of operator precedence.
(a++) is a post increment, so value of expression is 3.
(a++) is post increment, so value of expression is now 4.
Expression evaluation is happening from left to right.
3 * 4 = 12
Each time the you use a++, you're post-incrementing a. That means the first a++ evaluates to 3 and the second evaluates to 4. 3 * 4 = 12.
There is a general lack of understanding about how operators work. Honestly, every operator is syntactic sugar.
All you have to do is understand what is actually happening behind every 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)
Compound operators can then be rewritten using these generalizations (please ignore the return types for the sake of 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++);
as
Operators.set(a, 3)
Operators.set(a, Operators.multiply(Operators.postIncrement(a), Operators.postIncrement(a)));
Which can be split out using multiple variables:
Operators.set(a, 3)
Operators.set(b, Operators.postIncrement(a))
Operators.set(c, Operators.postIncrement(a))
Operators.set(a, Operators.multiply(b, c))
It's certainly more verbose that way, but it immediately becomes apparent that you never want to perform more than two operations on a single line.
In case of :
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 i.e. 12
hence we get output as 12.
In case of :
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
Main point to note here is that in this case compiler is solving from left to right and
in case of post increment, value before increment is used in calculation and as we move from left to right incremented value is used.
(a++) means return a and increment, so
(a++) * (a++) means 3 * 4
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 is what happens:
Pushes 3 into the stack then pops 3 from the stack and stores it at a.
Now a = 3 and the stack is empty.
0 iconst_3
1 istore_1 a
Now it pushes the value from "a" (3) into the stack, and then increments a(3 -> 4).
2 iload_1 [a]
3 iinc 1 1 [a]
So now "a" equals "4" the stack equals {3}.
Then it loads "a" again (4), pushes into the stack and increments "a".
6 iload_1 [a]
7 iinc 1 1 [a]
Now "a" equals 5 and the stack equals {4,3}
So it finally pops the fisrt two values from the stack (4 and 3), multiplies and stores it back into the stack (12).
10 imul
Now "a" equals 5 and the stack equals 12.
Finally is pops 12 from the stack and stores at a.
11 istore_1 [a]
TADA!
It is 12.
The expression starts evaluating from left. So it does:
a = (3++) * (4++);
Once the first part (3++) is evaluated, 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 since a is assigned with the value 12 after this.
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 ++ expression which changes the value based on the location.
Everyone has clearly explained the first expression, and why the value of a is 12.
For the follow on question, the answer is totally obvious to the casual observer:
17
Pre & post-prefix increments have a higher precedence than the multiplication operator. hence the expression is evaluated as 3*4.
If you use a++ the next time you use a it is incremented by one. So your doing
a = 3 * (3 + 1) = 3 * 4 = 12