о Java BigInteger - PullRequest
       5

о Java BigInteger

0 голосов
/ 19 января 2012

Я новичок в Java и просто пишу программу с 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 и ONE определены для типа BigInteger 0, 1 соответственно.

Я хочу, чтобы «i = 2» делило «n = 5», если «n mod i == 0», иначе «i ++», пока «n» не будет меньше или равно «i».

Я думаю, что вывод должен быть

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

и с эквивалентным кодом с примитивным типом int я получаю ожидаемый результат.

но это с BigInteger идет в бесконечный цикл

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

Кто-нибудь знает, почему это так?

Ответы [ 5 ]

10 голосов
/ 19 января 2012

Класс BigInteger представляет целые числа как неизменяемые объекты.

Здесь есть две точки.

  1. Не используйте ==, чтобы проверить, равны ли два BigInteger s
  2. Чтобы изменить значение переменной BigInteger, вы должны сделать i = i.add(ONE);, а не просто i.add(ONE);.

Причина не использовать == для сравнения BigInteger sпотому что вместо проверки на числовое равенство вы проверяете, что это один и тот же объект в памяти.

Рассмотрим с помощью String s.

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

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

В приведенном выше примере x.equals(y)истина, потому что они содержат одинаковое количество символов в одинаковом порядке.Однако x == y неверно, поскольку они являются различными объектами в памяти.

Причина, по которой вам необходимо присвоить результат арифметических операций переменной, заключается в том, что BigInteger является неизменным.Таким образом, арифметические операции не могут изменить значение объекта, с которым он работает, но он может создать новый BigInteger (который он возвращает).Вот почему вы должны присвоить результат арифметической операции переменной, в которой вы хотите его сохранить.

В качестве ярлыка для вашего lesserThanOrEqual это:

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

В основном

  • m == n становится m.compareTo(n) == 0
  • m != n становится m.compareTo(n) != 0
  • m < n становится m.compareTo(n) < 0
  • m > nстановится m.compareTo(n) > 0
  • m <= n становится m.compareTo(n) <= 0
  • m >= n становится m.compareTo(n) >= 0
1 голос
/ 19 января 2012

оба вышеприведенных ответа верны.Однако они не сообщают вам, что экземпляры BigInteger неизменны .Это означает, что они не меняются после установки.Вот почему вам нужно всегда присваивать результат преобразования ...

1 голос
/ 19 января 2012

Вы делаете это:

i.add(ONE);

Но вы должны сделать это:

i = i.add(ONE);
0 голосов
/ 19 января 2012

i.add(ONE) необходимо переназначить: i = i.add(ONE)

0 голосов
/ 19 января 2012

Вы не сохраняете результат, полученный с i.add(ONE). Это дает вам BigInteger объект, содержащий желаемое значение, но вы бросаете его на пол вместо того, чтобы назначить его на i.

...