Як користуватися BigInteger?


153

У мене є цей фрагмент коду, який не працює:

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

Змінна суми завжди 0. Що я роблю неправильно?


До речі, сума повинна легко вміститися int, тому вам не потрібно BigIntegerв цьому прикладі.
notnoop

8
Ні, я змінив код. Кількість більша, ніж 5000.
куб.

Питання пов'язаний як дублікат , здається, не має ті ж проблеми , як це питання (пов'язаний питання про якому функції використання так BigInteger може бути доданий, це один про те , як використовувати функцію додавання)
justhalf

Відповіді:


203

BigIntegerнезмінна. Javadocs зазначає, що додає () "[r] записує BigInteger, значення якого (це + val)." Отже, ви не можете змінити sum, вам потрібно переназначити результат addметоду на sumзмінну.

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

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

2
Що у своєму прикладі він не стане.
MarkPowell

105
Але чи справді так важко подумати, можливо, він спростив свій приклад до того, в чому саме полягає проблема?
thecoshman

@thecoshman - Ви цілком правильні, і кількість відгуків на ваш коментар показує, що це мудра порада для всіх читачів подібних питань. Деякий більш мудру пораду « читати те , що інші писали , перш ніж відповісти або коментування. » Наприклад , в даному випадку це навіть не вимагає НІЯКОЇ думки , так як OP чітко вказано , що він зробив це в коментарях нижче питання: " Ні, я змінили код. Кількість більша, ніж 5000. "
OMY

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

BigIntegerКлас є незмінним, отже , ви не можете змінити свій стан. Таким чином, виклик "додати" створює нове 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, і це робиться навіть у випадку Strings


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для цього достатньо. intстановить 32 біти, тоді longяк 64 біт, який може містити суму всіх значень int.


"Але чи справді так важко подумати, можливо, він спростив свій приклад до того, в чому саме полягає проблема?" (цитуючи thecoshman)
Bulwersator

5
Щодо цього питання, моя відповідь трохи відповідає нам. Оскільки тема зосереджена на тому, як використовувати BigInteger. Просто один із мого особистого досвіду, якщо ми хочемо підсумувати цілі числа, а числа не дуже великі, я вважаю за краще довгий. Тому що це просто у використанні та працює швидше. Для великомасштабного введення, BigInteger - хороший вибір.
frank.liu
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.