Fehlermeldung "Ganzzahl zu groß" für 600851475143


87
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();
    }
}

Wenn der obige Code ausgeführt wird, wird in der Zeile ein Fehler ausgegeben obj.function(600851475143);. Warum?


1
gibt es auch keinen unterschied zwischen "l" und "l"?
user446654

@ user446654: Nein, das gibt es. Letzteres ist besser lesbar. Lesen Sie dazu "Java Puzzler".
Adeel Ansari

@ user446654: Entwickeln von @ Thhilo-Gedanken über ein mögliches Speicherlimit, das überschritten wird Ich möchte meine 2 Münzen hinzufügen: Sie haben einen wirklich, wirklich schlechten Algorithmus für die Suche aller Teiler einer Zahl gewählt, wenn Sie mit so großen Zahlen wie in Ihrem Beispiel arbeiten möchten. Etwas, das auf dynamischer Programmierung basiert, würde wahrscheinlich besser funktionieren. Google darauf für weitere Ergebnisse.
Roman

1
PE-Tag hinzugefügt, Project Euler # 3
st0le

@ st0le: IMHO ist die Frage definitiv nicht nach der ursprünglichen Problemlösung, und was wir sehen, ist auch keine Lösung.
Roman

Antworten:


196

600851475143kann nicht als 32-Bit-Ganzzahl (Typ int) dargestellt werden. Es kann als 64-Bit-Ganzzahl (Typ long) dargestellt werden. lange Literale in Java enden mit einem "L":600851475143L


70

Suffix anhängen L: 23423429L.

Standardmäßig interpretiert Java alle Zahlenliterale als 32-Bit-Ganzzahlwerte. Wenn Sie explizit angeben möchten, dass dies eine größere als die 32-Bit-Ganzzahl ist, sollten Sie das Suffix Lfür lange Werte verwenden.


Für diejenigen, die eine gründlichere Erklärung suchen, warum diese Fehlermeldung auch nach dem Ändern des Variablentyps in angezeigt wirdlong , lesen Sie Folgendes
Joshua Pinter

29

Sie müssen ein langes Literal verwenden:

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

Aber ich würde erwarten, dass dieser Funktion der Speicher (oder die Zeit) ausgeht ...


16
Es ist eine bessere Praxis als das zu machen l, Großbuchstaben , so dass es aus leicht zu unterscheiden ist1
Bozho

2
@Bozho: Einverstanden. Aber ich habe einen Perl-Hintergrund. Ich codiere "nur schreiben" :-)
Thilo

Verwenden Sie "L" anstelle von "l"
Kevin V

13

Der Java-Compiler versucht, 600851475143 standardmäßig als konstanten Wert vom Typ int zu interpretieren. Dies verursacht einen Fehler, da 600851475143 nicht mit einem int dargestellt werden kann.

Um dem Compiler mitzuteilen, dass die Nummer so lange interpretiert werden soll, müssen Sie entweder loder Ldanach hinzufügen . Ihre Nummer sollte dann so aussehen 600851475143L.

Da es bei einigen Schriftarten schwierig ist, "1" und "l" in Kleinbuchstaben voneinander zu unterscheiden, sollten Sie immer "L" in Großbuchstaben verwenden.



4

Zur Kompilierungszeit wird die Nummer "600851475143" in einer 32-Bit-Ganzzahl dargestellt. Versuchen Sie stattdessen am Ende Ihrer Nummer ein langes Literal, um dieses Problem zu lösen.


3

Abgesehen von all den anderen Antworten können Sie Folgendes tun:

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

zum Beispiel :

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

1

Oder Sie können die Eingabenummer so lange deklarieren und dann den Code Tango ausführen lassen: 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;
        }
    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.