Explain the output of java code containing interfaces - java

I had come across a question for which I am not able to find out why its output is coming as
7
when I calculate mathematically it can produce output as 7, 8 or any other number So my question is on what basis its coming as 7 only
interface InterfaceA
{
int A = InterfaceB.B * 2;
}
interface InterfaceB
{
int B = InterfaceC.C + 1;
}
interface InterfaceC extends InterfaceA
{
int C = A + 1;
}
public class TestInterface implements InterfaceA, InterfaceB, InterfaceC {
public static void main(String[] args) {
System.out.println(A + B + C);
}
}

Obviously code like this should never actually occur. It's horrendous. I don't think you should spend too much time worrying about why it gives 7, but it's actually not too hard to see why.
The first field value to be evaluated is InterfaceA.A, so the VM starts to initialize InterfaceA. That requires InterfaceB.B, so it starts to initialize InterfaceB. That requires InterfaceC.C, so it starts to initialize InterfaceC.
Now although InterfaceC.C refers to InterfaceA.A, the VM is already initializing InterfaceA, so it just proceeds regardless (as per section 12.4.2 of the JLS):
If the Class object for C indicates that initialization is in progress for C by the current thread, then this must be a recursive request for initialization. Release LC and complete normally.
So InterfaceA.A is still 0 (we're still trying to work out what value it should have, and 0 is the default value for int), and InterfaceC.C gets a value of 1 (0 + 1). Then InterfaceB.B gets a value of 2 (1 + 1), and InterfaceA.A gets a value of 4 (2 * 2).
Sum all of those field values, and you end up with 7.
If you use a different expression, you'll get a different value because you'll see a different interface being initialized last, although it only depends on the first field which you refer to:
A + B + C = 7 (A = 4, B = 2, C = 1)
A + C + B = 7 (A = 4, B = 2, C = 1)
B + A + C = 3 (A = 0, B = 2, C = 1)
B + C + A = 3 (A = 0, B = 2, C = 1)
C + A + B = 6 (A = 2, B = 1, C = 3)
C + B + A = 6 (A = 2, B = 1, C = 3)
(You have to replace the existing line of code of course, as this is about type initialization - if you just add more System.out.println lines you'll get the same answer for all the above expressions.)

System.out.println(A + B + C);
When you asked for A ( InterfaceB.B * 2;) , you need B
So, B needs to be resolve,
int B = InterfaceC.C + 1;
When you asked for B ( InterfaceC.C + 1) , you need C
So, C needs to be resolve,
int C = A + 1; // 0+1 =1
A is not yet resolved and default is 0
So int C is 1.
Now , You need B.
int B = InterfaceC.C + 1; // 1+1 =2
Now
int A = InterfaceB.B * 2; // 2*2 =4
Finally
1+2+4 =7

When you run the code,then execution starts from the main method.In main its System.out.println(A+B+C) and as you know control goes from right to left.
Here in this case C is executed first(Because it is present at extreme right) meaning c=A+1 but A is 0 so C=1.
Now B is present to left of C so B will be executed this means B=C+1 so B=2(because c is already 1)
As A is at extreme left so Now A is executed this means A=B*2
So finally its 4+2+1=7
Similarly if you print System.out.println(B+C+A); then you will get 3

Related

Struggling to find the correct loop invariant

I have the following code:
public static void main(String[] args) {
int a = 3;
int b = 7;
int x = b; // x=b
int res = a; // res = a
int y = 1;
int invariant = 0;
System.out.println("a|b|x|y|res|invariant");
while (x > 0) {
if (x % 2 == 0) {
y = 2 * y;
x = x / 2;
} else {
res = res + y;
y = 2 * y;
x = (x - 1) / 2;
}
invariant = y + 2;
String output = String.format("%d|%d|%d|%d|%d|%d", a,b,x,y,res,invariant);
System.out.println(output);
}
// < res = a + b >
}
Which gives the following output:
a|b|x|y|res|invariant
3|7|3|2|4|4
3|7|1|4|6|6
3|7|0|8|10|10
However, if I change the numbers, the invariant isn't equal to the res anymore. Therefore my loop invariant for this problem is not correct.
I'm struggling really hard to find the correct loop invariant and would be glad if there's any hint that someone can give me.
My first impression after looking into the code and my results is that the loop invariant changes based on a and b. Let's say both a and b are odd numbers as they are in my example, then my Loop invariant is correct (at least it seems like it)
Is it correct to assume a loop variant like the following?
< res = y - 2 && a % 2 != 0 && b % 2 != 0 >
I did use different numbers and it seems like anytime I change them there's a different loop invariant and I struggle to find any pattern whatsoever.
I would really appreciate if someone can give me a hint or a general idea on how to solve this.
Thanks
This loop computes the sum a+b.
res is initialized to a.
Then, in each iteration of the loop, the next bit of the binary representation of b (starting with the least significant bit) is added to res, until the loop ends and res holds a+b.
How does it work:
x is initialized to b. In each iteration you eliminate the least significant bit. If that bit is 0, you simply divide x by 2. If it's 1, you subtract 1 and divide by 2 (actually it would be sufficient to divide by 2, since (x-1)/2==x/2 when x is an odd int). Only when you encounter a 1 bit, you have to add it (multiplied by the correct power of 2) to the result. y Holds the correct power of 2.
In your a=3, b=7 example, the binary representation of b is 111
In the first iteration, the value of res is a + 1 (binary) == a + 1 = 4
In the second iteration, the value of res is a + 11 (binary) == a + 3 = 6
In the last iteration, the value of res is a + 111 (binary) == a + 7 == 10
You could write the invariant as:
invariant = a + (b & (y - 1));
This takes advantage of the fact the at the end of the i'th iteration (i starting from 1), y holds 2^i, so y - 1 == 2^i - 1 is a number whose binary representation is i 1 bits (i.e. 11...11 with i bits). When you & this number with b, you get the i least significant bits of b.

Unary operator precedence in java

Now, according to this website, Unary post-increment has more precedence than Unary pre-increment. I presume it meant, that x++ is done before ++x.
However, when tried with the following expression, I've faced problems
int var1=10;
int b= --var1 + ++var1 + var1++;
Now, if var1++ executes first, then according to me,
b = --var1 + ++var1 + 10
Now, if I think it should do ++var1 before --var1, as it mentions that the Associativity is Right to Left. I suppose, it means do things on right, before the ones on the left
This, However, doesn't give the correct answer. The Correct Answer is 29, while I get 33. Why is it so ?
I presume it meant, that x++ is done before ++x.
No, it doesn't mean that. I've previously blogged about how I find viewing precedence in terms of execution order is problematic. It may well be valid in a computer-science-strict way, but it ends up confusing people.
I find it much easier to think about it as grouping. Likewise I think it's easiest to think of associativity as like precedence, but for operators of equal precedence. Evaluation order is always left-to-right.
So this:
int b = --var1 + ++var1 + var1++;
is grouped as if it were written:
int b = (--var1) + (++var1) + (var1++);
That's then equivalent to:
int b = ((--var1) + (++var1)) + (var1++);
(Due to binary + having left-to-right associativity.)
That's then effectively:
int tmp1 = --var1; // tmp1 = 9, var1 = 9
int tmp2 = ++var1; // tmp2 = 10, var1 = 10
int tmp3 = tmp1 + tmp2; // tmp3 = 19
int tmp4 = var1++; // tmp4 = 10, var1 = 11
int tmp5 = tmp3 + tmp4; // tmp5 = 29
int b = tmp5; // b = 29
... which confirms what you've observed.
Of course, you should always try to avoid having code as convoluted as this in the first place...
To demonstrate the evaluation order part, consider this expression:
int result = a() + b() * c();
Precedence means that's grouped as:
int result = a() + (b() * c());
That's equivalent to:
// Evaluate LHS of +, which is just a()
int tmp1 = a();
// Evaluate RHS of +, which is b() * c()
// First evaluate LHS of *, which is b()
int tmp2 = b();
// Next evaluate RHS of *, which is c()
int tmp3 = c();
// Now we can evaluate *:
int tmp4 = tmp2 * tmp3;
// Now we can evaluate +:
result = tmp1 + tmp4;
As we're executing methods, we can observe that execution order really easily:
public class Test {
public static void main(String[] args) throws Exception {
int result = a() + b() * c();
}
public static int a() {
System.out.println("a()");
return 3;
}
public static int b() {
System.out.println("b()");
return 4;
}
public static int c() {
System.out.println("c()");
return 5;
}
}
That prints:
a()
b()
c()
... which confirms the execution order shown in my expansion.
The sum --var1 + ++var1 + var1++ translates to:
9 + 10 + 10
since the various vars are changed as the sum is processed; obviously var1++ increments after the value is used, and ++var increments before it is used. The final value of var1 would be 11.

compound assignment operator in java [duplicate]

This question already has an answer here:
Order of operations for compound assignment operators in Java
(1 answer)
Closed 6 years ago.
int a = 2;
int b = 3;
int c = 10;
a +=(a += b) + c; // this will be same as --> a = a+((a= a+b) +c);
/* 2+((2=2+3)+10)
after adding 2+3
now value a = 5;
5 +((5)+10)
5 + (15)
a = 20
*/
System.out.println("a: "+a); // a:17
when i execute above program the answer is a:17 why not a:20 ?
according to me.
After resolving (a += b) now the value of a should be 5 then (a += b) + c would be 15 and after that a +=(a += b) + c; should be 20
please help me understand thanks.
The compound assignment operator stores the original value of the left operand before evaluating the second operand and performing the compound assignment (addition + assignment in this example).
Therefore
a += (a += b) + c;
is equivalent to :
int temp = a;
a = temp + (a += b) + c;
2 + 2 + 3 + 10 = 17
This is a good example of where order of evaluation and precedence don't match. They usually do which makes it confusing when there is a difference, as you mention the expression is evaluated left to right like this
int s = a; // stack
int t = a + b; // second stack value.
s += t;
s += c;
a = t;
a = s;
Note the (a+=b) is the same as (a+b) in this case.
In Java, you can replace a += b with a = a + b. And that is very important.
Hence your expression is equivalent to
a = a + (a = a + b) + c
Note that this will be evaluated as a = Term1 + Term2 + Term3 and in the order left to right.
Term1 is 2.
Term2 is the only tricky one. It is 5 (and has the side-effect of increasing a to 5 but that gets clobbered by the eventual assignment).
Term3 is 10.
That recovers the total, 17.
Note that the behaviour of this expression in C and C++ is undefined.
It is a bit tricky to understand. Although you have a += b on the right-hand side, that doesn't change the value of a that's used for the += at the beginning of the expression; that will still be 2. E.g.:
a += (a += b) + c;
a = 2 + (a[still 2] += 3) + 10
a = 2 + (5) + 10
a = 17
The a += b on the right-hand side is really just a a + b, since this is all on the right-hand side of a += already directed at a.
Details in JLS§15.26.2: Compound Assignment Operators.
First you do a+=b so 2+3 you have 5. Then a+= your answer (here 5) so 2+=5 = 7. Then 7+10 = 17

one-line swap without temp not working in Java? [duplicate]

This question already has answers here:
Why is "a^=b^=a^=b;" different from "a^=b; b^=a; a^=b;"?
(6 answers)
Closed 6 years ago.
I tried "swap variable in java without temp" in Java and I found something that bothers me:
int a = 1, b = 2;
b^= a ^= b ^= a;
System.out.println(a + " vs " + b);
The output shows
2 vs 0
However if I separate the leftmost assignment as a individual statement:
int a = 1, b = 2;
a ^= b ^= a;
System.out.println(a + " vs " + b);
b^=a;
System.out.println(a + " vs " + b);
The output is
2 vs 3
2 vs 1
Now the output is as expected.
In C++, the evaluation is ensured from right to left. What the difference, in terms of language spec, tells Java could lead such expected result?
According to the JLS, x ^= y is equivalent to x = (x) ^ (y) (there's also a cast in there, but if you're dealing with ints, the cast doesn't matter anyway). So this:
b ^= a ^= b ^= a;
is equivalent to
b = (b) ^ (a = (a) ^ (b = (b) ^ (a)));
// ^^^
In Java, arguments to an operator are always evaluated left to right. So the b that I pointed to in the above is the original value of b, since it's evaluated before the assignment to b in the right part of the expression. That means the expression is not equivalent to
b ^= a;
a ^= b;
b ^= a;
since the third statement uses the new value of b as the left operand to ^.

Fibbonacci sequence [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I'm having a little troubling understanding the code below. I've worked out the vales for each of the variables for each loop and I understand how the values for each variable change after each loop but I'm confused about how int a = b; represents the sum of the two previous values. I was stuck on this problem for a long time and solved the problem only through trial and error.
I really don't understand how int a = b; represents the sum of the two previous values. I was convinced that since int c = a + b; sums both variable a and variable b that was the variable i wanted to print in my program. Can you explain how int a represents the sum of the two previous values and why int c does not.
public class Fibonacci extends ConsoleProgram{
public void run(){
int i = 0;
int a = 0;
int b = 1;
while ( i <= 12) {
println(a);
i++;
int c = a + b;
a = b;
b = c;
}
}
}
I like to think of it as a staircase:
0
0 + 1 = 1
1 + 1 = 2
1 + 2 = 3
2 + 3 = 5
3 + 5 = 8
5 + 8 = 13
An arbitrary step would look like:
a + b = c
b + c = d
After the one step, c acts like b and b acts like a. But what about a and d? Since your solution is iterative, you just say that a becomes d and repeat the process again in a loop:
a + b = c
| b + c = a
|___________|
Or in code:
int a = 0;
int b = 1;
int c = 0;
while (true) {
c = a + b; // `a + b = c` isn't valid, so you have to flip it around.
a = b; // `b` "becomes" `a`
b = c; // `c` "becomes" `b`
c = a; // You don't need this step because `c` is just a temp variable
}
So what happens in this program is:
a = 0, b = 1
c is set to their sum, = 1
a is set to b, = 1
b is set to c, = 1
a = 1, b = 1
c is set to their sum, = 2
a is set to b, = 1
b is set to c, = 2
a = 1, b = 2
c is set to their sum, = 3
a is set to b, = 2
b is set to c, = 3
a = 2, b = 3
c is set to their sum, = 5
a is set to b, = 3
b is set to c, = 5
a = 3, b = 5
... And so on. You should get the idea :)

Categories