0

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);
}
Brian
  • 17,079
  • 6
  • 43
  • 66
CodeKingPlusPlus
  • 15,383
  • 51
  • 135
  • 216
  • Check out this question about mutating wrapper classes: http://stackoverflow.com/questions/4117793/are-java-wrapper-classes-really-immutable – MikeB Oct 02 '12 at 21:17
  • Have a look at my answer [here](http://stackoverflow.com/questions/12591294/how-can-i-delete-an-object-passed-into-a-java-method/12591366#12591366). It's not actually by reference, it's by the _value_ of the reference, so you can't actually change the original reference like you can change a pointer. – Brian Oct 02 '12 at 21:35
  • If performance is important, you should use `long` instead of `Long` Also use `double` instead of `Double` when you can. – Peter Lawrey Oct 02 '12 at 21:45

4 Answers4

8

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 a and b - either in a int[] or using a separate FactorizationRezult class that has two fields. That way you will declare a and b as 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 MutableLong and use a setValue(..) method - that way the changes will affect the object in the caller method. This is less advisable

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
3

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.

user207421
  • 305,947
  • 44
  • 307
  • 483
1

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.

Arash Shahkar
  • 655
  • 3
  • 12
  • 24
0

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.

Alex Coleman
  • 7,216
  • 1
  • 22
  • 31