Reputation: 1943
I have a bit of confusion with the following expression. Here it is:
char a = 'D';
int b = 5;
System.out.println(a++/b+--a*b++);
I am trying to solve it in the following way:
('D'/b+--a*b++);
Behind the scenes, a = 'E'
'D'/b+'D'*b++;
'D'/b + 'D' * 5;
Behind the scenes b
value is incremented to 6, b = 6
'D'/6 + 'D' *5;
11 + 'D' * 5;
11 + 345
Since 'D' value is 69 in ASCII
356
But the compiler gives the output as 353. What is the mistake which I am doing it here?
Upvotes: 0
Views: 82
Reputation:
What you are calculating is
(a++ / b) + (--a * b++)
In this expression, --a
cancels the a++
: After the division a
has the value E
, but before the multiplication it again has the value D
. Post increment and pre decrement cancel each other. So the first operand for /
and *
each is 'D'
which is 68
. The post increment b++
has no effect on the expression. So you do
(68 / 5) + (68 * 5)
which is 353
using integer rounding.
Edit: In detail, this is what happens:
char a = 'D';
int b = 5;
int divisonResult = a / b;
// a++ and --a cancel each other.
a++; // The incrementation of a happens after the divison.
--a; // The decrementation of a happens before the multiplication.
// Now a is back to 'D'.
int multiplicationResult = a * b;
b++; // This has no effect since b takes no part in the last step:
int additionResult = divisonResult + multiplicationResult;
Upvotes: 4
Reputation: 54
As pointed out by Lurz Horn i made a mistake in my old answer, my tests passed because the error was less then 1 and was cut of by integer. So i quickly edited my tests and i'm working now with doubles.
It honestly interested me too so i took it apart step by step in the form of unit tests. The last test shows best how the compiler does it.
@Test
public void test1() throws Exception {
char a = 'D';
double b = 5;
double result = a++ / b + --a * b++;
assertThat(result, is(closeTo(353.6, 0.001)));
}
@Test
public void test2() throws Exception {
char a = 'D';
double b = 5;
double aDividedB = a++ / b;
double result = aDividedB + --a * b++;
assertThat(result, is(closeTo(353.6, 0.001)));
}
@Test
public void test3() throws Exception {
char a = 'D';
double b = 5;
double aDividedB = a / b;
a++;
double result = aDividedB + --a * b++;
assertThat(result, is(closeTo(353.6, 0.001)));
}
@Test
public void test4() throws Exception {
char a = 'D';
double b = 5;
double aDividedB = a / b;
a++;
double aTimesB = --a * b++;
double result = aDividedB + aTimesB;
assertThat(result, is(closeTo(353.6, 0.001)));
}
@Test
public void test5() throws Exception {
char a = 'D';
double b = 5;
double aDividedB = a / b;
a++;
a--;
double aTimesB = a * b++;
double result = aDividedB + aTimesB;
assertThat(result, is(closeTo(353.6, 0.001)));
}
@Test
public void test6() throws Exception {
char a = 'D';
double b = 5;
double aDividedB = a / b;
a++;
a--;
double aTimesB = a * b;
b++;
double result = aDividedB + aTimesB;
assertThat(result, is(closeTo(353.6, 0.001)));
}
Upvotes: 0