Бесконечный цикл при вычислении мощности больших целых чисел Java

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

public static BigInteger powerOfBigInteger (BigInteger base, BigInteger power){
    if (power == BigInteger.valueOf(0)){
        return BigInteger.valueOf(1);
    }

    if (power == BigInteger.valueOf(1)){
        return base;
    }

    BigInteger x = BigInteger.valueOf(1);
    while (x != power ){
        base.multiply(base);
        x.add(BigInteger.valueOf(1));
        System.out.println(x + " " + power);
                   return base;
    } 

    return base;

Я запускаю это, и, по-видимому, x никогда не равняется мощности. Любая помощь приветствуется.


person user1446565    schedule 14.06.2012    source источник
comment
Зачем внедрять этот метод? BigInteger уже имеет метод pow(int), и любая мощность, слишком большая, чтобы поместиться в int, все равно приведет к нехватке памяти.   -  person Louis Wasserman    schedule 14.06.2012


Ответы (4)


Ты должен сделать

if (BigInteger.ZERO.equals(power)) return BigInteger.ONE;
if (BigInteger.ONE.equals(power))  return base;

и вы должны накапливать результат вашего умножения и сложения, потому что BigInteger неизменяем и возвращает новый экземпляр BigInteger

Бесконечный цикл возникает из-за того, что ваш x НИКОГДА не меняется — должно быть

x = x.add(BigInteger.ONE);

умножение должно измениться на

result = result.mulitply(base);

где начальное значение результата должно быть BigInteger.ONE

person Eugene Ryzhikov    schedule 14.06.2012
comment
Спасибо. Как глупо с моей стороны не установить x в новое значение, я не совсем понял BigInteger. - person user1446565; 14.06.2012

Я вижу, что вы сравниваете, используя == вместо .equals. Сравнивать предметы с равными.

public static BigInteger powerOfBigInteger (BigInteger base, BigInteger power){
    if (power.equals(BigInteger.valueOf(0))){
        return BigInteger.valueOf(1);
    }

    if (power.equals(BigInteger.valueOf(1))){
        return base;
    }

    BigInteger x = BigInteger.valueOf(1);
    while (!x.equals(power)){
        base.multiply(base);
        x.add(BigInteger.valueOf(1));
        System.out.println(x + " " + power);
                   return base;
    } 

    return base;
}
person tjg184    schedule 14.06.2012

Я вижу, вы используете == с BigInteger. Не делай этого. Вместо этого используйте .equals(other). BigInteger не является примитивом, который можно сравнить с обычными операторами (вы просто сравниваете ссылки на объекты, которые, скорее всего, не будут равны). Кроме того, вы ничего не настраиваете, когда выполняете вычисления на своих экземплярах BigInteger; они не работают с локальным объектом и сохраняют результат в локальном объекте. Вам нужно сохранить возвращенный объект.

Проблемные строки:

  • base.multiply(base);
  • x.add(BigInteger.valueOf(1));

В этом другом посте на SO re также есть некоторые обсуждения. BigInteger в степени BigInteger: BigInteger.pow(BigInteger)?

person Chris Dennett    schedule 14.06.2012

Может быть, я что-то упускаю, но разве это не так просто, как тот факт, что он выполняет base.multiply(base). При расчете мощности основание должно оставаться заданным. Пример 2 ^ 3 должен генерировать последовательность 2,4,8, но этот код будет генерировать 2,4,16, потому что после первого цикла основание равно четырем, а four.multiple(four) равно 16, а не 8. Я должен пропустить что-то.

person Thomas Jay Rush    schedule 23.12.2016