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?

user446654
quelle
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

Yuliy
quelle
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.

römisch
quelle
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 ...

Thilo
quelle
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.

josefx
quelle
6

Sie benötigen 40 Bit, um das Ganzzahlliteral 600851475143 darzustellen. In Java beträgt der maximale Ganzzahlwert jedoch 2 ^ 31-1 (dh Ganzzahlen sind 32 Bit, siehe http://download.oracle.com/javase/1.4.2/docs) /api/java/lang/Integer.html ).

Das hat nichts damit zu tun function. Versuchen Sie stattdessen, ein langes ganzzahliges Literal zu verwenden (wie in den anderen Antworten vorgeschlagen).

Andre Holzner
quelle
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.

JVM
quelle
3

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

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

zum Beispiel :

obj.function(Long.parseLong("600851475143"));
Anand Undavia
quelle
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;
        }
    }
}
Milen.Jeremic
quelle