How is A *= B *= A *= B evaluated?
Asked Answered
S

2

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

Spessartite answered 22/8, 2019 at 22:27 Comment(3)
the first A *= uses the original value of A, not the result from later operationsCristencristi
Closely related: Why is “a^=b^=a^=b;” different from “a^=b; b^=a; a^=b;”?Sacco
The assignments are evaluated right to left.Overmuch
L
6

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
Liter answered 22/8, 2019 at 22:33 Comment(0)
T
5

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
Trenchant answered 22/8, 2019 at 22:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.