This question already has an answer here:
How are java increment statements evaluated in complex expressions
(1 answer)
Closed 8 years ago.
I know there are several question about the x++ operation, I know the difference between ++x and x++. But now I have to solve this:
int x = 5;
x += x++ * x++ * x++;
Well I know that this shouldn't be too difficult, but still, I need an explanation how this calculatino is done, step by step, I don't get it by myself..
Your code is equivalent to:
int x = 5;
int originalX = x;
int a = x++;
int b = x++;
int c = x++;
x = originalX + a * b * c;
System.out.println("x = " + x); //215
x += x++ * x++ * x++;
can be written as:
x = x+ x++ * x++ * x++;
how will it be evaluated?
x= 5+(5 * 6 * 7) because you are using postfix. So, the incremented value of x will be visible from the second time it is used.
So, final output = 5+ (5*6*7) == 215
x++ would mean read the value and use it in the place which is referenced and then increment it.
So in your question:-
int x = 5;
x = 5 + 5 * 6 * 7
x += x++ * x++ * x++;
x = 215
int x = 5;
x += x++ * x++ * x++;
First, set some brackets to better see the calculation sequence:
x += ((x++ * x++) * x++);
Then, replace the first occurance of x with it's value, calculate, and continiue replacing with updated values:
5 += ((x++ * x++) * x++);
5 += ((5 * x++) * x++);
5 += ((5 * 6) * x++);
5 += ((5 * 6) * 7);
5 += 210;
and now, it's plain math...
Result should be: 215
And my compile gives me: 215
So I think my explanation is correct. But i'm not 100% sure...
Related
i have problem to step by step java expression calculation
System.out.println(++x + x++ * y-- - --y);
I know this precedence:
1. postfix unary
2. prefix unary
3. multiplicative
4. additive
but when i calculate with this precedence the result is below:
// 12 + 11 * 19 - 18
can some one help me
You can understand it from the example given below:
public class Main {
public static void main(String[] args) {
int x = 5, y = 10;
System.out.println(++x + x++ * y-- - --y);// 6 + 6 * 10 - 8 = 58
}
}
Steps in this calculation:
++x = 6
6 + x++ * y-- = 6 + 6 * 10 = 6 + 60 = 66 (after this y will become 9 because of y-- and x will become 7 because of x++ but this increased value of x has never been used in subsequent calculation)
66 - 8 = 58 (before y gets subtracted from 66, it will become 8 because of --y)
Postfix unary is applied after the variable evaluation, opposite to prefix, which is applied before evaluation, your expression can be rewrited:
int x_prefix = x + 1; // ++x
int y_prefix = y - 1; // --y
System.out.println(x_prefix + x * y - y_prefix);
int x = x + 1; // x++
int y = y - 1; // y--
You write operators precedence, it's right but every operator has own behavior, in case of postfix increment, of course has to be evaluate before others, but its behavior is return the current variable and after increment its value.
NOTE: I just rewrited your expression as is, if you use in the same expression the variable postfix incremented, the next access see the variable incremented:
int x = 1;
System.out.println(x++ + x++); // 1 + 2
System.out.println(x) // 3
For completeness:
int x = 1;
System.out.println(++x + ++x); // 2 + 3
System.out.println(x) // 3
I'm trying to run some elliptic curve results in java, but the modulo operator doesn't seem to output the right results.
int a = 17;
double previousx = 4;
double previousy = 14;
double xnew;
double ynew;
double sigma;
double convert;
for (int i = 1; i < 10; i++) {
convert = 0;
for (int j = 0; i<60; j++) {
if (((2 * previousy * j) % 59) == 1) {
convert = j;
break;
}
}
sigma = ((3 * Math.pow(previousx, 2) + a) * convert) % 59;
xnew = ((sigma * sigma) - (2 * previousx)) % 59;
ynew = (sigma * (previousx - xnew) - previousy) % 59;
System.out.println((Math.pow(2, i)) + "x P: " + xnew + "," + ynew + " Sigma:" + sigma);
previousx = xnew;
previousy = ynew;
}
output of the first iteration:
2.0x P: 8.0,-57.0 Sigma:55.0
8 and 55 are correct, but -57 mod 59 = 2 and not -57. How do I fix this?
8 and 55 are correct, but -57 mod 59 = 2 and not -57. How do I fix this?
The % operator in Java isn't modulus - it's the remainder operator. It's behaving entirely correctly according to the language specification. When you suspect that Java is misbehaving, it's always worth checking the specification to see whether it's actually your expectations which are incorrect.
If you want a modulus operator, you just need to check whether the result is negative, and if so add the divisor again:
int remainder = (2 * previousy * j) % 59;
int modulus = remainder < 0 ? remainder + 59 : remainder;
if (modulus == 1) {
...
}
Alternatively, in your case:
int remainder = (2 * previousy * j) % 59;
if (remainder == 1 || remainder == -58) {
...
}
... and adjust the rest of your uses of % as appropriate too, of course.
Additionally, as Stijn de Witt mentioned, it looks like you've got a typo in your inner loop condition.
It looks to me like you have a typo in the inner loop:
for (int j = 0 ; i<60 ; j++)
It says i<60 in a loop that is iterating over j...
I'd try fixing that.
As to the original question... Can you reduce your test case? If you maintain that modulo is not working correctly for some numbers then why not make a single statement that does a modulo on those numbers and prints the results?
I have two similar questions about operator precedences in Java.
First one:
int X = 10;
System.out.println(X++ * ++X * X++); //it prints 1440
According to Oracle tutorial:
postfix (expr++, expr--) operators have higher precedence than prefix (++expr, --expr)
So, I suppose that evaluation order:
1) first postfix operator: X++
1.a) X++ "replaced" by 10
1.b) X incremented by one: 10+1=11
At this step it should look like: System.out.println(10 * ++X * X++), X = 11;
2) second POSTfix operator: X++
2.a) X++ "replaced" by 11
2.b) X incremented by one: 11+1=12
At this step it should look like: System.out.println(10 * ++X * 11), X = 12;
3) prefix operator: ++X
3.a) X incremented by one: 12+1=13
3.b) ++X "replaced" by 13
At this step it should look like: System.out.println(10 * 13 * 11), X = 13;
4) evaluating 10*13 = 130, 130*11 = 1430.
But Java seems to ignore PRE/POST ordering and puts them on one level. So the real order:
X++ -> ++X -> X++
what causes the answer to be (10 * 12 * 12) = 1440.
Second one:
Example from this question:
int a=1, b=2;
a = b + a++;
Part of accepted answer:
"By the time of assignment, ++ has already incremented the value of a to 2 (because of precedence), so = overwrites that incremented value."
OK, let's look step-by-step:
1) replacing "b" with 2
2) replacing "a++" with 1
3) incrementing "a" by 1 -> at this point a==2
4) evaluating 2+1 = 3
5) overwriting incremented value of "a" with 3
Seems everything is fine.
But let's make a little change in that code (replace "=" with "+=")
a += b + a++;
steps 1-4 should be same as above.
so, after step 4 we have something like that:
a += 3;
where a==2
And then I think: OK, a = 2+3, so a should be 5. BUT the answer is only 4
I'm really confused. I already spent couple of hours but still can't understand where I am wrong.
P.S. I know, that I shouldn't use this "style" in real applications. I just want to understand what is wrong in my thoughts.
The confusion stems from the fact that the operands are evaluated from left to right. This is done first, before any attention is paid to operator precedence/order of operations.
This behavior is specified in JLS 15.7.2. Evaluate Operands before Operation
So X++ * ++X * X++ is first evaluated as 10 * 12 * 12 which yields, as you saw, 1440.
To convince yourself of this, consider the following:
X = 10; System.out.println(X++ * ++X);
X = 10; System.out.println(++X * X++);
If X++ were done first, then ++X second, then multiplication, both should print the same number.
But they do not:
X = 10; System.out.println(X++ * ++X); // 120
X = 10; System.out.println(++X * X++); // 121
So how does this make sense? Well if we realize that operands are evaluated from left to right, then it makes perfect sense.
X = 10; System.out.println(X++ * ++X); // 120 (10 * 12)
X = 10; System.out.println(++X * X++); // 121 (11 * 11)
The first line looks like
X++ * ++X
10 (X=11) * (X=12) 12
10 * 12 = 120
and the second
++X * X++
(X=11) 11 * 11 (X=12)
11 * 11 = 121
So why are prefix and postfix increment/decrement operators in the table?
It is true that increment and decrement must be performed before multiplication. But what that is saying is that:
Y = A * B++
// Should be interpreted as
Y = A * (B++)
// and not
Y = (A * B)++
Just as
Y = A + B * C
// Should be interpreted as
Y = A + (B * C)
// and not
Y = (A + B) * C
It remains that the order of the evaluation of the operands occurs left-to-right.
If you're still not conviced:
Consider the following program:
class Test
{
public static int a(){ System.out.println("a"); return 2; }
public static int b(){ System.out.println("b"); return 3; }
public static int c(){ System.out.println("c"); return 4; }
public static void main(String[] args)
{
System.out.println(a() + b() * c());
// Lets make it even more explicit
System.out.println(a() + (b() * c()));
}
}
If the arguments were evaluated at the time they were needed, either b or c would come first, the other next, and lastly a. However, the program outputs:
a
b
c
14
a
b
c
14
Because, regardless of the order that they're needed and used in the equation, they're still evaluated left to right.
Helpful reading:
What are the rules for evaluation order in Java?
a += a++ * a++ * a++ in Java. How does it get evaluated?
Appendix A: Operator Precedence in Java
In short,
Precedence is like preparing the expression to be calculated by putting parentheses. Evaluation comes next from left to right considering each pair of parentheses as a separate operation.
For example,if i=2 then i+i++ becomes i+(i++) after precedence and evaluates to 2+2 = 4.
However, i+++i becomes (i++)+i and evaluates to 2+3 = 5.
Same to i+(i=5) which evaluates to 2+5 = 7.
In fact the postfix operators do have higher precedence than prefix operators. For example, i+++++i becomes ((i++)++)+i after precedence which gives a compile error (the second postfix operator needs a variable to operate on but a value is found instead!). If both postfix and prefix operators had had equal precedence then the expression would have become (i++)+(++i) and evaluates to 2+4 = 6.
If you need more explanation you can compile and run the following code and inspect the examples printed at the output.
public class TestPrecedence {
public static void main(String[] str) {
int i = 0;
System.out.println("\n");
i = 2; System.out.println("i = " + i + "\n");
i = 2; System.out.println("i++ = " + i++ + "\n");
i = 2; System.out.println("++i = " + ++i + "\n");
i = 2; System.out.println("i++i = (i++)i TestPrecedence.java:8: error: ')' expected\n"+
" i++i\n"+
" ^\n");
i = 2; System.out.println("i+-i = i+(-i) = " + (i+-i) + "\n");
i = 2; System.out.println("++i++ = ++(i++) TestPrecedence.java:12: error: unexpected type\n"+
" ++i++ \n"+
" ^\n"+
" required: variable\n"+
" found: value\n");
i = 2; System.out.println("i+++++i = ((i++)++)+i TestPrecedence.java:17: error: unexpected type\n"+
" i+++++i\n"+
" ^\n"+
" required: variable\n"+
" found: value\n");
i = 2; System.out.println("i++ + ++i = " + (i++ + ++i) + "\n");
i = 2; System.out.println("i+(i=3) = " + (i+(i=3)) + " evaluates left to right\n");
i = 2; System.out.println("i+i++ precedence yields i+(i++) evaluates to 2+2 = " + (i+i++) + "\n");
i = 2; System.out.println("i+++i precedence yields (i++)+i evaluates to 2+3 = " + (i+++i) + "\n");
System.out.println("\n");
}
}
The reason why its 1440 is because
x is set to 10 i.e 1st term is FIXED(overall equation 10 *)
x is incremented by 1,x =11 now
x is pre-incremented by 1 x=12 and second term FIXED now (overall equation 10 * 12 *)
now x is set to 12 and third term FIXED(overall equation 10 * 12 *12)
x is increment now but is in this case not used for evaluation,
in short a term is FIXED when variable occurs which in this case is X
2nd case:
I'm not sure but I guess can be broken as,
a=b+a
a++
which I think is what is happening.
For the second one ->
int a=1, b=2;
a += b + a++;
Compiler will convert it to
a = a + b + a++;
Then apply your logic and you will find the reason why a is 4.
First step
1) first postfix operator: X++
1.a) X++ "replaced" by 10
1.b) X incremented by one: 10+1=11
At this step it should look like: System.out.println(10 * ++X * X++), X = 11;
2) prefix operator: ++X
2.a) X "replaced" by 11
2.b) X incremented by one: 11+1=12
At this step it should look like: System.out.println(10 * 12 * X++), X = 12;
3) second POSTfix operator: X++
3.a) X "replaced" by 12
3.b) X incremented by one: 12+1=13
At this step it should look like: System.out.println(10 * 12 * 12), X = 13;
This prints 10 * 12 * 12 = 1440
This is the bytecode for the first step
1. bipush 10
2. istore_0
3. getstatic java/lang/System/out Ljava/io/PrintStream;
4. iload_0
5. iinc 0 1
6. iinc 0 1
7. iload_0
8. imul
9. iload_0
10. iinc 0 1
11. imul
12. invokevirtual java/io/PrintStream/println(I)V
13. return
This do the following:
1. Push 10 to the stack
2. Pop 10 from the stack to X variable
3. Push X variable value (10) to the stack
5. Increment local variable X (11)
6. Increment local variable X (12)
7. Push X variable value (12) to the stack
8. Multiply top and subtop (10*12) Now Top = 120
9. Push X variable value (12) to the stack
10. Increment local variable X (13)
11. Multiply top and subtop (120*12) Now Top = 1440
Notice than the last increment (10.) is done after the push of X to the stack
Sorry, I couldn't think of a better title.
Anyway, when I compile the following code:
class Example{
public static void main(String[] args) throws Exception {
int x = 3;
x -= 2 + x++ == 4 ? x++ : ++x;
System.out.println("x = " + x);
}
}
I get the answer -2.
Now I would really like to know how it comes to this answer, as I can't find it.
It would be amazing if I could get an answer to this, as this may be on a exam that I'll have somewhat soon.
Note: Of course I wouldn't ever code out something like this myself, this is just an exercise.
Thanks so much if you can help me out!
Edit: answer to fge's answer:
Okay, thanks! but now if I change it up a little and make it like so:
x = 2;
x += 3 + ++x == 6 ? x-- : x--;
System.out.println("x = " + x);
I would think that you would get the following:
++x == 6
is not true, as x is now 3. this means we get x--, making it now 2 again.
then we get 3 + 2 = 5, so the expression can be evaluated to:
x += 5
because x is now 2, we get 2 + 5 = 7.
When you create such code example
int x = 3;
System.out.println(2 + x++ == 4 ? x++ : ++x);
you will see that the output is 5. It is because it is equivalent to
(2 + x++) == 4 ? x++ : ++x
so first Java will evaluate (2+ x++). Since we have x++ value of x will be returned first creating (2+3) and then incremented, so x will be now 4 after it.
Since (2+3) == 4 is false because (5 == 4) we will execute this part ++x, first incrementing x to 5 and then returning it.
Now lets go back to your example
int x = 3;
x -= 2 + x++ == 4 ? x++ : ++x;
You may know that x -= y is in fact x = x - y so it can be written as
x = x - (2 + x++ == 4 ? x++ : ++x);
So, since Java evaluates from left to right it will be
x = 3 - (2 + x++ == 4 ? x++ : ++x);
We know now that (2 + x++ == 4 ? x++ : ++x) is in fact 5 so
x = 3 - 5; // == -2
I know Math.sin() can work but I need to implement it myself using factorial(int) I have a factorial method already below are my sin method but I can't get the same result as Math.sin():
public static double factorial(double n) {
if (n <= 1) // base case
return 1;
else
return n * factorial(n - 1);
}
public static double sin(int n) {
double sum = 0.0;
for (int i = 1; i <= n; i++) {
if (i % 2 == 0) {
sum += Math.pow(1, i) / factorial(2 * i + 1);
} else {
sum += Math.pow(-1, i) / factorial(2 * i + 1);
}
}
return sum;
}
You should use the Taylor series. A great tutorial here
I can see that you've tried but your sin method is incorrect
public static sin(int n) {
// angle to radians
double rad = n*1./180.*Math.PI;
// the first element of the taylor series
double sum = rad;
// add them up until a certain precision (eg. 10)
for (int i = 1; i <= PRECISION; i++) {
if (i % 2 == 0)
sum += Math.pow(rad, 2*i+1) / factorial(2 * i + 1);
else
sum -= Math.pow(rad, 2*i+1) / factorial(2 * i + 1);
}
return sum;
}
A working example of calculating the sin function. Sorry I've jotted it down in C++, but hope you get the picture. It's not that different :)
Your formula is wrong and you are getting a rough result of sin(1) and all you're doing by changing n is changing the accuracy of this calculation. You should look the formula up in Wikipedia and there you'll see that your n is in the wrong place and shouldn't be used as the limit of the for loop but rather in the numerator of the fraction, in the Math.pow(...) method. Check out Taylor Series
It looks like you are trying to use the taylor series expansion for sin, but have not included the term for x. Therefore, your method will always attempt to approximate sin(1) regardless of argument.
The method parameter only controls accuracy. In a good implementation, a reasonable value for that parameter is auto-detected, preventing the caller from passing to low a value, which can result in highly inaccurate results for large x. Moreover, to assist fast convergence (and prevent unnecessary loss of significance) of the series, implementations usually use that sin(x + k * 2 * PI) = sin(x) to first move x into the range [-PI, PI].
Also, your method is not very efficient, due to the repeated evaluations of factorials. (To evaluate factorial(5) you compute factorial(3), which you have already computed in the previous iteration of the for-loop).
Finally, note that your factorial implementation accepts an argument of type double, but is only correct for integers, and your sin method should probably receive the angle as double.
Sin (x) can be represented as Taylor series:
Sin (x) = (x/1!) – (x3/3!) + (x5/5!) - (x7/7!) + …
So you can write your code like this:
public static double getSine(double x) {
double result = 0;
for (int i = 0, j = 1, k = 1; i < 100; i++, j = j + 2, k = k * -1) {
result = result + ((Math.pow(x, j) / factorial (j)) * k);
}
return result;
}
Here we have run our loop only 100 times. If you want to run more than that you need to change your base equation (otherwise infinity value will occur).
I have learned a very good trick from the book “How to solve it by computer” by R.G.Dromey. He explain it like this way:
(x3/3! ) = (x X x X x)/(3 X 2 X 1) = (x2/(3 X 2)) X (x1/1!) i = 3
(x5/5! ) = (x X x X x X x X x)/(5 X 4 X 3 X 2 X 1) = (x2/(5 X 4)) X (x3/3!) i = 5
(x7/7! ) = (x X x X x X x X x X x X x)/(7 X 6 X 5 X 4 X 3 X 2 X 1) = (x2/(7 X 6)) X (x5/5!) i = 7
So the terms (x2/(3 X 2)) , (x2/(5 X 4)), (x2/(7 X 6)) can be expressed as x2/(i X (i - 1)) for i = 3,5,7,…
Therefore to generate consecutive terms of the sine series we can write:
current ith term = (x2 / ( i X (i - 1)) ) X (previous term)
The code is following:
public static double getSine(double x) {
double result = 0;
double term = x;
result = x;
for (int i = 3, j = -1; i < 100000000; i = i + 2, j = j * -1) {
term = x * x * term / (i * (i - 1));
result = result + term * j;
}
return result;
}
Note that j variable used to alternate the sign of the term .