Как использовать BigInteger?


153

У меня есть этот кусок кода, который не работает:

BigInteger sum = BigInteger.valueOf(0);
for(int i = 2; i < 5000; i++) {
    if (isPrim(i)) {
        sum.add(BigInteger.valueOf(i));
    }
}

Переменная sum всегда равна 0. Что я делаю не так?


Кстати, сумма должна легко вписаться int, поэтому вам не нужно BigIntegerдля этого примера.
Notnoop

8
Нет, я изменил код. Число больше 5000.
Копия.

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

Ответы:


203

BigIntegerнеизменен. Javadocs утверждает, что add () «[r] переворачивает BigInteger, значение которого (this + val)». Таким образом, вы не можете изменить sum, вам нужно переназначить результат addметода sumпеременной.

sum = sum.add(BigInteger.valueOf(i));

1
int будет достаточно до тех пор, пока вы не пройдете 2 ^ 31-1, долго будет достаточно до тех пор, пока вы не пройдете 2 ^ 63-1.
Жан Хоминал

2
Что, в его примере, он не будет.
МаркПауэлл

105
Но неужели так сложно думать, может быть, он упростил свой пример до того, в чем именно заключается проблема?
thecoshman

@thecoshman - Вы совершенно правы, и количество голосов в вашем комментарии показывает, что это мудрый совет для всех читателей таких вопросов. Еще один мудрый совет - « прочитайте то, что написали другие, прежде чем отвечать или комментировать». Например, в этом случае он даже не требует ЛЮБОЙ мысли, так как ФП четко заявил, что он сделал именно это в комментариях под вопросом: « Нет, я изменил код. Номер больше 5000. "
OMY

58
sum = sum.add(BigInteger.valueOf(i))

BigIntegerКласс является неизменным, следовательно , вы не можете изменить свое состояние. Поэтому вызов «add» создает новый BigInteger, а не модифицирует текущий.


22

Другие ответы прибили это; BigInteger является неизменным. Вот небольшое изменение, чтобы этот код работал.

BigInteger sum = BigInteger.valueOf(0);
for(int i = 2; i < 5000; i++) {
    if (isPrim(i)) {
        sum = sum.add(BigInteger.valueOf(i));
    }
}

11

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


11

java.math.BigIntegerявляется неизменным классом, поэтому мы не можем назначить новый объект в месте расположения уже назначенного объекта. Но вы можете создать новый объект для назначения нового значения, например:

sum = sum.add(BigInteger.valueOf(i));

3

Да, это неизменно

sum.add(BigInteger.valueOf(i));

поэтому метод add () класса BigInteger не добавляет новое значение BigIntger к своему собственному значению, но создает и возвращает новую ссылку BigInteger без изменения текущего BigInteger, и это то, что делается даже в случае строк


0

На самом деле вы можете использовать,

BigInteger sum= new BigInteger("12345");

для создания объекта для класса BigInteger. Но проблема здесь в том, что вы не можете дать переменную в двойных кавычках. Так что нам нужно использовать метод valueOf (), и мы должны снова сохранить ответ в этой сумме. Так что мы напишем,

sum= sum.add(BigInteger.valueOf(i));

0

Bigintegerнеизменный класс. Вам необходимо явно присвоить значение вашего вывода сумме следующим образом:

sum = sum.add(BigInteger.valueof(i));    

4
Теперь это восьмой ответ с тем же объяснением, так как этот ответ полезен?
Том

-6

Поскольку вы суммируете некоторые значения int вместе, нет необходимости использовать BigInteger. longдля этого достаточно. int32 бита, а long64 бита, которые могут содержать сумму всех значений int.


«Но неужели так сложно подумать, может быть, он упростил свой пример до того, в чем именно заключается проблема?» (цитируя thecoshman)
Bulwersator

5
На этот вопрос мой ответ немного наш размах. Поскольку тема сосредоточена на том, как использовать BigInteger. Просто один из моего личного опыта: если мы хотим суммировать некоторые целые числа, а цифры не очень большие, я бы предпочел долго. Потому что это легко использовать и работает быстрее. BigInteger - хороший выбор для крупномасштабного ввода.
frank.liu
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.