Komunikat o błędzie „Zbyt duża liczba całkowita” dla 600851475143


89
public class Three {
    public static void main(String[] args) {
        Three obj = new Three();
        obj.function(600851475143);
    }

    private Long function(long  i) {
        Stack<Long> stack = new Stack<Long>();

        for (long j = 2; j <= i; j++) {
            if (i % j == 0) {
                stack.push(j);
            }
        }
        return stack.pop();
    }
}

Uruchomienie powyższego kodu powoduje błąd w wierszu obj.function(600851475143);. Czemu?


1
też nie ma różnicy między „l” i „L”?
user446654

@ user446654: Nie, jest. Ta ostatnia jest bardziej czytelna. Przeczytaj „Java Puzzler”.
Adeel Ansari

@ user446654: ewoluujące myśli @Thilo o możliwym przekroczeniu limitu pamięci Chcę dodać moje 2 monety: wybrałeś naprawdę zły algorytm wyszukiwania wszystkich dzielników liczby, jeśli chcesz operować na tak dużych liczbach, jak w twoim przykładzie. Coś opartego na programowaniu dynamicznym prawdopodobnie działałoby lepiej. Google na to, aby uzyskać dalsze wyniki.
Roman

1
Dodano tag PE, Project Euler # 3
st0le

@ st0le: IMHO pytanie zdecydowanie nie dotyczy oryginalnego rozwiązania problemu, a to, co widzimy, również nie jest rozwiązaniem.
Roman

Odpowiedzi:


200

600851475143nie może być reprezentowany jako 32-bitowa liczba całkowita (typ int). Może być reprezentowany jako 64-bitowa liczba całkowita (typ long). długie literały w Javie kończą się literą „L”:600851475143L


71

Dołączająca sufiks L: 23423429L.

Domyślnie java interpretuje wszystkie literały liczbowe jako 32-bitowe wartości całkowite. Jeśli chcesz wyraźnie określić, że jest to coś większego niż 32-bitowa liczba całkowita, powinieneś używać sufiksu Ldla długich wartości.


Dla tych, którzy szukają dokładniejszego wyjaśnienia, dlaczego otrzymujesz ten komunikat o błędzie nawet po zmianie typu zmiennej na long, przeczytaj to: stackoverflow.com/a/8924925/293280
Joshua Pinter

29

Musisz użyć długiego literału:

obj.function(600851475143l);  // note the "l" at the end

Ale spodziewałbym się, że tej funkcji zabraknie pamięci (lub czasu) ...


17
uważa się, że lepszą praktyką ljest 1
pisanie

2
@Bozho: Zgoda. Ale mam doświadczenie w Perlu. Koduję „tylko do zapisu” :-)
Thilo

Użyj „L” zamiast „l”
Kevin V

13

Kompilator java domyślnie próbuje zinterpretować 600851475143 jako stałą wartość typu int. Powoduje to błąd, ponieważ 600851475143 nie może być reprezentowane przez int.

Aby powiedzieć kompilatorowi, że chcesz, aby liczba była interpretowana tak długo, musisz dodać albo lalbo Lpo niej. Twój numer powinien wtedy wyglądać tak600851475143L .

Ponieważ niektóre czcionki utrudniają odróżnienie od siebie „1” i małych liter „l”, należy zawsze używać dużej litery „L”.



4

W czasie kompilacji liczba „600851475143” jest reprezentowana jako 32-bitowa liczba całkowita, zamiast tego spróbuj użyć długiego literału na końcu numeru, aby rozwiązać ten problem.


3

Oprócz wszystkich innych odpowiedzi, możesz zrobić:

long l = Long.parseLong("600851475143");

na przykład :

obj.function(Long.parseLong("600851475143"));

1

Lub możesz zadeklarować liczbę wejściową jako długą, a następnie pozwól jej wykonać kod tango: D ...

public static void main(String[] args) {

    Scanner in = new Scanner(System.in);
    System.out.println("Enter a number");
    long n = in.nextLong();

    for (long i = 2; i <= n; i++) {
        while (n % i == 0) {
            System.out.print(", " + i);
            n /= i;
        }
    }
}
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.