user1124390
user1124390

Reputation: 93

about Java BigInteger

I'm new to Java and just code a program with BigInteger.

public static void main(String[] args) {
  BigInteger n = new BigInteger("5");
  BigInteger i = new BigInteger("2");
  while (lesserOrEqual(i,n) {
    System.out.println("n.mod(i) = "+n.mod(i));
    if (n.mod(i) == ZERO) {
      n = n.divide(i);
    }
    else {
      i.add(ONE);
  }
  System.out.println("n = "+n);
  System.out.println("i = "+i);
}


public static boolean lesserOrEqual(BigInteger m, BigInteger n) `{
  if (m.compareTo(n) == -1 || m.compareTo(n) == 0)
    return true;
  return false;
}

ZERO and ONE are defined of the type BigInteger 0, 1, respectively.

I want "i=2" to divide "n=5", if "n mod i == 0", else "i++", until "n" to be lesser or equal to "i".

I think the output must be

n.mod(i) = 1
n = 5
i = 3
n.mod(i) = 2
n = 5
i = 4
n.mod(i) = 1
n = 5
i = 5
n.mod(i) = 0
n = 1
i = 5

and with the equivalent code with primitive type int, I have the result as expected.

but this with BigInteger goes to infinite loop

n.mod(i) = 1
n = 5
i = 2
...

Does anyone know why it is so?

Upvotes: 0

Views: 1755

Answers (5)

Dunes
Dunes

Reputation: 40683

The BigInteger class represents integers as immutable objects.

There are two points here.

  1. Don't use == to test if two BigIntegers are equal
  2. To change the value of a BigInteger variable you must do i = i.add(ONE); and not just i.add(ONE);.

The reason not to use == to compare BigIntegers is because instead of checking for numerical equality you are checking that they are the same object in memory.

Consider with Strings.

String a = "a";
String b = "b";

String x = a + b;
String y = "ab";

In the above example x.equals(y) is true because they contain the same number of characters in exactly the same order. However, x == y is not true because they are different objects in memory.

The reason you need to to assign the result of arithmetic operations to a variable is because BigInteger is immutable. Thus arithmetic operations cannot change the value of the object it is operating on, but it can create a new BigInteger (which it returns). Which is why you must assign the result of the arithmetic operation to the variable you want it saved in.

As an aside a shortcut for your lesserThanOrEqual to is this.

boolean result = m.compareTo(n) <= 0;

Basically

  • m == n becomes m.compareTo(n) == 0
  • m != n becomes m.compareTo(n) != 0
  • m < n becomes m.compareTo(n) < 0
  • m > n becomes m.compareTo(n) > 0
  • m <= n becomes m.compareTo(n) <= 0
  • m >= n becomes m.compareTo(n) >= 0

Upvotes: 10

juergen d
juergen d

Reputation: 204746

You are doing this:

i.add(ONE);

But you should do this:

i = i.add(ONE);

Upvotes: 1

hvgotcodes
hvgotcodes

Reputation: 120168

both of the above answers are right. They are not telling you, however, that BigInteger instances are immutable. That means they don't change once set. That is why you need to always assign the result of a transformation...

Upvotes: 1

Wojciech Owczarczyk
Wojciech Owczarczyk

Reputation: 5735

i.add(ONE) has to be reassigned: i = i.add(ONE)

Upvotes: 0

Pops
Pops

Reputation: 30818

You're not saving the result that gets returned from i.add(ONE). It's giving you a BigInteger object containing the desired value, but you're dropping it on the floor instead of assigning it to i.

Upvotes: 0

Related Questions