Could you explain step by step how java evaluates
1) the value of y ?
int x = 5;
int y = x-- % x++;
2) the value of y in this case?
int x = 5;
int y = x-- * 3 / --x;
Well, the operands are evaluated from left to right, and in each case the result of a postfix operation is the value of the variable before the increment/decrement whereas the result of a prefix operation is the value of the variable after the increment/decrement... so your cases look like this:
Case 1:
int x = 5;
int tmp1 = x--; // tmp1=5, x=4
int tmp2 = x++; // tmp2=4, x=5
int y = tmp1 % tmp2; // y=1
Case 2:
int x = 5;
int tmp1 = x--; // tmp1=5, x=4
int tmp2 = 3;
int tmp3 = --x; // tmp3=3, x=3
int y = tmp1 * tmp2 / tmp3; // y = 5
Personally I usually try to avoid using pre/post-increment expressions within bigger expressions, and I'd certainly avoid code like this. I find it's almost always clearer to put the side-effecting expressions in separate statements.
I'm not sure about java but in C it evolved into undefined behaviour.
Related
Running this code will return 11 while I was expecting 20. Why is that so?
int x = 1;
int y = x + (x = 10);
System.out.println(y);
Evaluation is from left to right. So
int y = x + (x = 10);
is (with x initially 1):
int y = 1 + 10;
Putting the assignment in () doesn't make it come first. It just ensures that it's a valid expression, since y = x + x = 10 would be y = (x + x) = 10 which would require assigning to something (x + x) that wasn't a variable.
If you want 20, put the assignment first:
int y = (x = 10) + x;
Of course, the vast majority of the time, it's best to avoid these kinds of side-effects and assign x a value outside the expression, breaking the expression up if necessary. Assignment-within-expression can be useful sometimes (particularly while ((blah = getNextBlah()) != null) sort of things), but only in limited situations.
I have this code :
public static int rsnpeasant(int x, int y) {
if ((y & 1) == 0) {
y = y / 2;
x = x * 2;
rsnpeasant(x, y);
} else {
sum = sum + x;
y = y / 2;
y = y - 1 / 2;
x = x * 2;
if (y == 1) {
sum = total;
return total;
} else {
rsnpeasant(x, y);
}
}
total = sum;
return total;
}
The error is happening on the first rsnpeasant(x,y); line in the first if statement. It seems to be forever looping to that line even though it's supposed to go to the else statement if y is odd. If y is divided by 2 it should become odd at some point.
Link is what im trying to code
y=y-1/2...
Order of operations will evaluate the 1/2 and subtract that from y. In integer arithmetic, 1/2 is 0. I think you want y=(y-1)/2.
Your principal problem is that you are trying to divide an int primitive type, if y = 1, dividing that value by 2 will return 0, then you pass it to the method again, it will always be stuck in the first if statement.
You should return a double, float or bigdecimal in your method, and use one of those types for the parameters too.
I came across this problem in this website, and tried it in Eclipse but couldn't understand how exactly they are evaluated.
int x = 3, y = 7, z = 4;
x += x++ * x++ * x++; // gives x = 63
System.out.println(x);
y = y * y++;
System.out.println(y); // gives y = 49
z = z++ + z;
System.out.println(z); // gives z = 9
According to a comment in the website, x += x++ * x++ * x++ resolves to x = x+((x+2)*(x+1)*x) which turns out to be true. I think I am missing something about this operator precedence.
Java evaluates expressions left to right & according to their precedence.
int x = 3, y = 7, z = 4;
x (3) += x++ (3) * x++ (4) * x++ (5); // gives x = 63
System.out.println(x);
y = y (7) * y++ (7);
System.out.println(y); // gives y = 49
z = z++ (4) + z (5);
System.out.println(z); // gives z = 9
Postfix increment operator only increments the variable after the variable is used/returned. All seems correct.
This is pseudocode for the postfix increment operator:
int x = 5;
int temp = x;
x += 1;
return temp;
From JLS 15.14.2 (reference):
The value of the postfix increment expression is the value of the variable before the new value is stored.
Nothing to do with operator precedence per se, just the order of evaluation.
Two things to know here:
x++ is the postfix increment, so the value of x is incremented after it is evaluated
* evaluates the right side then the left side.
Considering point 2, the expression x++ * x++ * x++ can be rewritten more specifically as x++ * (x++ * (x++)).
The whole expression can be written as the procedures:
a = x
x += 1
b = x
x += 1
c = a*b
d = x
x += 1
return c*d
The postfix operator x++ means something like "give me the value of x now, but increment it for future references"
So, by the order of operations and evaluation,
x++ * x++ * x++
is interpreted first as
3 * 4 * 5 (=60)
Which is then added to the original 3, yielding 63.
The original value is used because it's on the same line, had you written something like:
int x = 3;
int y += x++ * x++ * x++;
x += y;
x would now be 66, instead of 63 because the x in the second line is now 6, rather than its original 3.
Because the increment Operation ++ is added after the variable x. That's a post increment operation. That means, x is incremented after the operation is handled.
In your example the expression would be:
x += 3 * 4 * 5
First the expression is added by 3 (x+=....)
then the first x++ results in 3
the second x++ results in 4 (because it was incremented before)
and the third x++ results in 5.
If you want your variable incremented before the operation is executed, you have to write ++x (pre increment operation)
Because a postincrement modifies the variable after the value is taken and += evaluates its left hand side before evaluating its right hand side,
x += x++ * x++ * x++;
becomes
tmp0 = x
tmp1 = x
++x
tmp2 = tmp1 * x
++x
tmp3 = tmp2 * x
++x
x = tmp0 + x
unary operators evaluated left to right, so the first x++ gets the value x, the second is (x+1), etc. And the += evaluates according to the value of x at the start, hence the addition of x
I've misplaced += with =+ one too many times, and I think I keep forgetting because I don't know the difference between these two, only that one gives me the value I expect it to, and the other does not.
Why is this?
a += b is short-hand for a = a + b (though note that the expression a will only be evaluated once.)
a =+ b is a = (+b), i.e. assigning the unary + of b to a.
Examples:
int a = 15;
int b = -5;
a += b; // a is now 10
a =+ b; // a is now -5
+= is a compound assignment operator - it adds the RHS operand to the existing value of the LHS operand.
=+ is just the assignment operator followed by the unary + operator. It sets the value of the LHS operand to the value of the RHS operand:
int x = 10;
x += 10; // x = x + 10; i.e. x = 20
x =+ 5; // Equivalent to x = +5, so x = 5.
+= → Add the right side to the left
=+ → Don't use this. Set the left to the right side.
a += b equals a = a + b. a =+ b equals a = (+b).
x += y
is the same as
x = x + y
and
x =+ y
is wrong but could be interpreted as
x = 0 + y
It's simple.
x += 1 is the same as x = x + 1 while
x =+ 1 will make x have the value of (positive) one
Some historical perspective: Java inherited the += and similar operators from C. In very early versions of C (mid 1970s), the compound assignment operators had the "=" on the left, so
x =- 3;
was equivalent to
x = x - 3;
(except that x is only evaluated once).
This caused confusion, because
x=-1;
would decrement x rather than assigning the value -1 to it, so the syntax was changed (avoiding the horror of having to surround operators with blanks: x = -1;).
(I used -= and =- in the examples because early C didn't have the unary + operator.)
Fortunately, Java was invented long after C changed to the current syntax, so it never had this particular problem.
Because =+ is not a Java operator.
Please help. I've been working on this non stop and can't get it right. The issue I'm having is that the output I'm getting for the inverse is always 1.
This is the code that I have (it computes GCD and trying to modify so it also computes a^-1):
import java.util.Scanner;
public class scratchwork
{
public static void main (String[] args)
{
Scanner keyboard = new Scanner(System.in);
long n, a, on, oa;
long gcd = 0;
System.out.println("Please enter your dividend:");
n= keyboard.nextLong();
System.out.println("Please enter your divisor:");
a= keyboard.nextLong();
on= n;
oa= a;
while (a!= 0)
{gcd=a;
a= n% a;
n= gcd;
}
System.out.println("Results: GCD(" + odd + ", " + odr + ") = " + gcd);
long vX; vS; vT; vY; q; vR; vZ; m; b;
vX = n; vY=a;
vS = 0; vT = 1; m=0; b=0;
while (a != 0)
{
m=vT;;
b=vX;
q = n / a;
vR = vS - q*vT;
tZ = n - q*a;
vS = vT; n = da;
vT = tY; dY = vZ;
}
if (d>1) System.out.println("Inverse does not exist.");
else System.out.println("The inverse of "+oa+" mod "+on+" is "+vT);
}
}
The code you've posted does not declare most of the variables it uses and thus dues not compile. Most importantly, the variable v it uses to output the result is neither defined nor assigned to anywhere in the posted code - whatever it contains has nothing to do with the calculation.
Can we see the variables declaration? If you mix integer with double, your numbers can be rounded. Anyway, if you only want the inverse, juste use Math.pow(a, -1);
Also, in the second loop, you never set "a" so it will loop forever:
while (a != 0)
{
m=vT;;
b=vX;
q = n / a;
vR = vS - q*vT;
tZ = n - q*a;
vS = vT; n = da;
vT = tY; dY = vZ;
}
#Justin,
Thanks. I was able to figure out how to print out the variables in each loop. I basically had to put my loop up with the GCD loop...that was it. 2 weeks worth of work and I had just to move where the loop was.
It works! I'm sorry but I'm doing a happy dance over here.
Here's a solution in Python that should be easily translatable into Java:
def euclid(x, y):
"""Given x < y, find a and b such that a * x + b * y = g where, g is the
gcd of x and y. Returns (a,b,g)."""
assert x < y
assert x >= 0
assert y > 0
if x == 0:
# gcd(0,y) = y
return (0, 1, y)
else:
# Write y as y = dx + r
d = y/x
r = y - d*x
# Compute for the simpler problem.
(a, b, g) = euclid(r, x)
# Then ar + bx = g -->
# a(y-dx) + bx = g -->
# ay - adx + bx = g -->
# (b-ad)x + ay = g
return (b-a*d, a, g)
def modinv(x, n):
(a, b, g) = euclid(x%n, n)
assert g == 1
# a * x + b * n = 1 therefore
# a * x = 1 (mod n)
return a%n
It uses the stack, but Euclid's algorithm takes O(log n) steps so you won't have a stack overflow unless your numbers are astronomically high. One could also translate it into a non-recursive version with some effort.