Jak korzystać z BigInteger?


153

Mam ten fragment kodu, który nie działa:

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

Zmienna sumująca zawsze wynosi 0. Co robię źle?


Nawiasem mówiąc, suma powinna łatwo zmieścić się int, więc nie potrzebujesz BigIntegertego przykładu.
— notnoop

8
Nie, zmieniłem kod. Liczba jest większa niż 5000.
— cc.

Pytanie powiązane jako zduplikowane nie wydaje się mieć tego samego problemu co to pytanie (powiązane pytanie dotyczy tego, której funkcji użyć, aby można było dodać BigInteger, to jest o tym, jak korzystać z funkcji dodawania)
— prostu połowę

Odpowiedzi:


203

BigIntegerjest niezmienna. Element javadocs stwierdza, że add () „[r] et zwraca BigInteger, którego wartość to (this + val)”. Dlatego nie możesz zmienić sum, musisz ponownie przypisać wynik addmetody do sumzmiennej.

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

1
int wystarczy, o ile nie przekroczysz 2 ^ 31-1, długość będzie wystarczająca, o ile nie przekroczysz 2 ^ 63-1.
— Jean Hominal

2
Czego, w jego przykładzie, nie zrobi.
— MarkPowell

105
Ale czy naprawdę trudno pomyśleć, że może uprościł swój przykład do dokładnie tego, na czym polega problem?
— thecoshman

@thecoshman - Masz rację, a liczba pozytywnych głosów w Twoim komentarzu pokazuje, że jest to mądra rada dla wszystkich czytelników takich pytań. Bardziej mądrą radą jest „ przeczytaj to, co napisali inni, zanim odpowiesz lub skomentujesz ” . Na przykład w tym przypadku nie wymaga to nawet ŻADNEJ myśli, ponieważ OP wyraźnie stwierdził, że właśnie to zrobił w komentarzach pod pytaniem: „ Nie, ja zmienił kod. Liczba jest większa niż 5000. ”
— OMY,

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

BigIntegerKlasa jest niezmienna, a więc nie można zmienić jego stan. Więc wywołanie „add” tworzy nowy BigInteger, zamiast modyfikować bieżący.


22

Inne odpowiedzi potwierdziły to; BigInteger jest niezmienny. Oto drobna zmiana, aby kod działał.

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

11

BigInteger to niezmienna klasa. Więc za każdym razem, gdy wykonujesz jakąkolwiek arytmetykę, musisz ponownie przypisać wynik do zmiennej.


11

java.math.BigIntegerjest niezmienną klasą, więc nie możemy przypisać nowego obiektu w lokalizacji już przypisanego obiektu. Ale możesz utworzyć nowy obiekt, aby przypisać nową wartość, na przykład:

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

3

Tak, jest niezmienny

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

więc metoda add () klasy BigInteger nie dodaje nowej wartości BigIntger do swojej własnej wartości, ale tworzy i zwraca nową referencję BigInteger bez zmiany obecnego BigInteger i tak jest nawet w przypadku Strings


0

Właściwie możesz użyć,

BigInteger sum= new BigInteger("12345");

do stworzenia obiektu dla klasy BigInteger, ale problem polega na tym, że nie możesz podać zmiennej w podwójnych cudzysłowach, więc musimy użyć metody valueOf () i musimy ponownie zapisać odpowiedź w tej sumie.

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

0

Bigintegerjest niezmienną klasą. Musisz jawnie przypisać wartość swojego wyniku do sumy w następujący sposób:

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

4
To jest teraz ósma odpowiedź z tym samym wyjaśnieniem, więc jak ta odpowiedź jest pomocna?
— Tom

-6

Ponieważ sumujesz razem niektóre wartości int, nie ma potrzeby używania BigInteger. longwystarczy do tego. intto 32 bity, a long64 bity, które mogą zawierać sumę wszystkich wartości int.


- Ale czy naprawdę trudno pomyśleć, że może uprościł swój przykład do dokładnie tego, na czym polega problem? (cytując thecoshman)
— Bulwersator,

5
Na to pytanie moja odpowiedź jest nieco ograniczona. Ponieważ temat skupia się na tym, jak używać BigInteger. To jedno z moich osobistych doświadczeń, jeśli chcemy podsumować niektóre liczby całkowite, a liczby nie są dość duże, wolałbym długie. Ponieważ jest łatwy w użyciu i działa szybciej. W przypadku danych wejściowych na dużą skalę dobrym wyborem jest BigInteger.
— frank.liu
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.