• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Can you solve this puzzle?

 
Bob Young
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Interested in a puzzle with a twist? I came across this example and it took me awhile to get a grasp on it.
public class Test {
public static void main(String[] args) {
int i = 0;
i = i++;
i = i++;
i = i++;

System.out.println("i = " + i);
}
}

output is 0 (zero). Not the possibly expected value of 3! Following the rules for the increment operator it almost makes sense.

i++ first evaluates i(as 0), assigns the result back to i(which is 0). The twist is that the increment never seems to happen. You can see this by changing i to say -1. and the result will be -1, change it to 10 and the result will be 10, add more i = i++; lines and you will get the initial value of i. Remove all but one line of i = i++; and you still get whatever the initial value of i is set to.

One question is why is the increment lost? If you take a slightly different code as follows the increment will happen as it should.

public class Test {
public static void main(String[] args) {
int j, i = 3;
j = i++ - i++; // j= i++ (1st) - i++ (2nd)
System.out.println("i = " + i);
System.out.println("j = " + j);
}
}
results are i = 5 and j = -1. The 1st i++ is evaluated as - initial value of i is 3 then the increment to 4 happens. The 2nd i++ is evaluated as - initial value of i is now 4 and then
the increment to 5 happens. Here the incrementing is happening as the evaluation of the code is moving down the line of code. Which all makes sense. All this explaination was needed to
show that the incrementing is taking place right after the evaluation of each expression (i++) while in the very first example I believe that the incrementing is somehow not being performed.
Any thoughts as to why?
 
Cindy Glass
"The Hood"
Sheriff
Posts: 8521
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The JVM has a "working area" where it holds the current value of variables.
In the first example i is set =0, then i is set = to iteslf so it is still 0. The working area is then incremented to 1. The evaluation is now over and the working area is thrown away. The you start AGAIN. i is set = to itself so it is still 0 etc. etc. etc.
In the second case you only have ONE evaluation and it is using the same working area. j=i so it is 3, then the working area for i is incremented to 4, when the i variable is referenced a second time, the current value of 4 is pulled from the working area so 3-4= -1. Then the working value of i is incremented to 5.
The interesting thing is that you are not putting any results back into i, which allows the system to use what it knows the current value of i to be instead of what you forced it to be with the assignment operator (=) in the first example.
If you change the second example replacing the j = with i = , then you will force the JVM to put the -1 back into i effectively loosing the 5 value that it would have been,
 
Bob Young
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One quick followup; is the working area defined to be the current line of code until it reaches the ;?
As always, I appreciate your typically clear answers, except perhaps when I stumble upon a post which has an added animation recanting that "Cindy did not say this"! Sorry I couldn't help myself. I doooooo really thank you for your effort on this board.
 
Cindy Glass
"The Hood"
Sheriff
Posts: 8521
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Such harrassement, I tell you . . . But thank you.
The "working area" is a term I invented to describe however the vendor chose to implement the JVM specs. But the simple answer is yes, it is in place until the evaluation and assignment is complete, which would terminate with a semi-colon.
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When you increase the value of i and assign the value to i it remains 0. Insted try this programme:
public class Test {
public static void main(String[] args) {
int i = 0;
int j = i++;
i = i++;
i = i++;
System.out.println("i = " + i);
}
}
In this case the value of i will be printed as 1. As only second time we are assigning the value of i to itself. First tim we are assigning it to j.
****************************************************************
Originally posted by Bob Young:
Interested in a puzzle with a twist? I came across this example and it took me awhile to get a grasp on it.
public class Test {
public static void main(String[] args) {
int i = 0;
i = i++;
i = i++;
i = i++;

System.out.println("i = " + i);
}
}

output is 0 (zero). Not the possibly expected value of 3! Following the rules for the increment operator it almost makes sense.

i++ first evaluates i(as 0), assigns the result back to i(which is 0). The twist is that the increment never seems to happen. You can see this by changing i to say -1. and the result will be -1, change it to 10 and the result will be 10, add more i = i++; lines and you will get the initial value of i. Remove all but one line of i = i++; and you still get whatever the initial value of i is set to.

One question is why is the increment lost? If you take a slightly different code as follows the increment will happen as it should.

public class Test {
public static void main(String[] args) {
int j, i = 3;
j = i++ - i++; // j= i++ (1st) - i++ (2nd)
System.out.println("i = " + i);
System.out.println("j = " + j);
}
}
results are i = 5 and j = -1. The 1st i++ is evaluated as - initial value of i is 3 then the increment to 4 happens. The 2nd i++ is evaluated as - initial value of i is now 4 and then
the increment to 5 happens. Here the incrementing is happening as the evaluation of the code is moving down the line of code. Which all makes sense. All this explaination was needed to
show that the incrementing is taking place right after the evaluation of each expression (i++) while in the very first example I believe that the incrementing is somehow not being performed.
Any thoughts as to why?


------------------
 
Cindy Glass
"The Hood"
Sheriff
Posts: 8521
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So now I am re-reading Bob's second statement, and I think that I need to re-word some things.
First, in the first reply, perhaps when I said "the working area is thrown away", what I SHOULD have said is that the value that is in the working area is thrown away, because it overlaid with the assignment value. The actual tracking mechanism for i is not thrown away.
Second, the working area is in place until all evaluation and assignments of i are complete (more that just one statement).. I think this MAY come under the category of 'recanting that "Cindy did not say this"! ' In other words there is on-going tracking of what i should be, but when you explicitly assign a value back to i it overlays the value that the system was keeping.
Actually the example that Hrishikesh gave is good in that it shows that i was 0, then j was set to the 0 that i was, the working area for i is incremented to 1, then i is set to the value of the working area (which is now 1) and the working area is incremented to 2, but the assignment sets it back to 1. Then again i is set to the working area which is 1 and the working area is set to two, then the assignment sets it back to 1. So it prints 1.
PS: NO HARRASSING (I'm very sensitive you know - - - )(not )
 
Matts Smith
Ranch Hand
Posts: 113
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi there,
here my my explanation of the i = i++; statement.
i++ could be expanded to this code (THIS IS NOT FOR REAL... JUST SO YOU UNDERSTAND)

so the value of i is returned before it is incremented but the incrementation occurs before the end of the statement. So when you assign the return value to i it will undo the incrementation
later
 
ryan burgdorfer
Ranch Hand
Posts: 219
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Matts,
That's a great way to explain it. I may have to steal that one from you for use when someone egts confused in the future over the post-increment/decrement op.
------------------
  • Ryan Burgdorfer
  • Java Acolyte in
  • Columbus, OH USA
 
Cindy Glass
"The Hood"
Sheriff
Posts: 8521
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Good explaination Matts!!!
 
Ashutosh Uprety
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Let me use some bookish terms and it should make things better.
Its a classic example of POST-INCREMENT operation which jogs ppl in the 1st instance.
i=0
i = i++ ...
take it this way ...
m = i++ ... what is m ?? 0
Now someone by chance replaced 'm' with 'i', so what is i ?? it is zero bacause m = 0 ( since value of 'i' increases AFTER it is assigned to m)
Keep repeating this 1 million times.. u still get zero.
So u can write the whole thing as :-
i=0;
m = i++;
i=m
Quite naturally i = 0.
Now eat this :-
{
int i = 0;
i = ++i;
i = ++i;
i = ++i;
System.out.println("i = " + i);
}
The result is 3.
This is becoz this is a PER-INCREMENT operation which u can also write as
i = 0;
i = i+1;
m = i;
So m=1 ... do this 1 million times ... The answer is 1 million.
What say u !!!
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic