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.