In the function fermatFactorization(), a and b are being passed as reference parameters, since I am using the Long Class. However, in function testFermatFactorization() when I pass a and b to fermatFactorization(), the values of a and b do not get changed, and so testFermatFactorization() prints (0)(0). I tested this by printing out a and b in fermatFactorization(), and I got the output that I expected.
What am I overlooking? Could the compiler alter a and b in fermatFactorization() since they are only being assigned to?(doubtful)
public static void fermatFactorization(Long n, Long a, Long b)
//PRE: n is the integer to be factored
//POST: a and b will be the factors of n
{
Long v = 1L;
Long x = ((Double)Math.ceil(Math.sqrt(n))).longValue();
//System.out.println("x: " + x);
Long u = 2*x + 1;
Long r = x*x - n;
while(r != 0) //we are looking for the condition x^2 - y^2 - n to be zero
{
while(r>0)
{
r = r - v; //update our condition
v = v + 2; //v keeps track of (y+1)^2 - y^2 = 2y+1, increase the "y"
}
while(r<0)
{
r = r + u;
u = u + 2; //keeps track of (x+1)^2 - x^2 = 2x+1, increases the "x"
}
}
a = (u + v - 2)/2; //remember what u and v equal; --> (2x+1 + 2y+1 - 2)/2 = x+y
b = (u - v)/2; // --> (2x+1 -(2y+1))/2 = x-y
}
public static void testFermatFactorization(Long number)
{
Long a = 0L;
Long b = 0L;
fermatFactorization(number, a, b);
System.out.printf("Fermat Factorization(%d) = (%d)(%d)\n", number, a, b);
}
Java is pass by value. If you assign a new value to the argument, it won't affect the value in the caller method.
You have two options:
make your method return
aandb- either in aint[]or using a separateFactorizationRezultclass that has two fields. That way you will declareaandbas local variables in your called method, rather than taking them as parameters. This is the most advisable approach.An alternative approach is to use a
MutableLongand use asetValue(..)method - that way the changes will affect the object in the caller method. This is less advisable
a and b are references, not 'reference parameters', and they are passed by value. The values are changed in the called method but that has no effect on the caller.
There is no 'pass by reference' in Java.
In Java, everything is passed by value. There is no call-by-reference. Even when you pass an Object, it's reference is passed by value. So, when you pass a Long object, you are simply passing the reference to it by value.
Long, just like other primitive type wrappers, is "immutable". You can't change the long value it has inside. So, if you don't want to change your design, you have to make a mutable wrapper for long yourself (or use MutableLong) and pass it on. Changing your design to return the results instead of changing the method arguments is a much better way if you ask me.
Using the = operator clears out the spot in the memory where the local variable is stored and replaces it. This will not affect the original variable. Pass by value only allows you to modify data in in object (like modifying a field in it), not it's actual reference.
来源:https://stackoverflow.com/questions/12698414/java-pass-by-reference-and-compiler-optimization