Messaggio di errore "Numero intero troppo grande" per 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();
    }
}

Quando il codice precedente viene eseguito, produce un errore nella riga obj.function(600851475143);. Perché?


1
inoltre non c'è differenza tra "l" e "L"?
user446654

@ user446654: No, c'è. Quest'ultimo è più leggibile. Leggi "Java Puzzler" per questo.
Adeel Ansari

@ user446654: evoluzione di @Thilo pensieri sul possibile superamento del limite di memoria Voglio aggiungere le mie 2 monete: hai scelto un algoritmo davvero, davvero pessimo per cercare tutti i divisori di un numero se vuoi operare con numeri così grandi come nel tuo esempio. Qualcosa basato sulla programmazione dinamica probabilmente funzionerebbe meglio. Google su questo per ulteriori risultati.
Roman

1
Aggiunto tag PE, Progetto Eulero # 3
corso il

@ st0le: IMHO la domanda non riguarda assolutamente la soluzione del problema originale, e anche quello che vediamo non è una soluzione.
Roman

Risposte:


200

600851475143non può essere rappresentato come numero intero a 32 bit (tipo int). Può essere rappresentato come un numero intero a 64 bit (tipo long). i letterali lunghi in Java terminano con una "L":600851475143L


71

Append suffisso L: 23423429L.

Per impostazione predefinita, java interpreta tutti i letterali numerici come valori interi a 32 bit. Se vuoi specificare esplicitamente che questo è qualcosa di più grande dell'intero a 32 bit, dovresti usare il suffisso Lper i valori lunghi.


Per coloro che cercano una spiegazione più approfondita del motivo per cui viene visualizzato questo messaggio di errore anche dopo aver modificato il tipo di variabile in long, leggi questo: stackoverflow.com/a/8924925/293280
Joshua Pinter

29

Devi usare un letterale lungo:

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

Ma mi aspetto che quella funzione esaurisca la memoria (o il tempo) ...


17
è considerata una pratica migliore per rendere il lmaiuscolo, in modo che sia facilmente distinguibile da1
Bozho

2
@ Bozho: d'accordo. Ma ho un background in Perl. Codice "solo scrittura" :-)
Thilo

Usa "L" invece di "l"
Kevin V,

13

Il compilatore java tenta di interpretare 600851475143 come valore costante di tipo int per impostazione predefinita. Ciò causa un errore poiché 600851475143 non può essere rappresentato con un int.

Per dire al compilatore che vuoi il numero interpretet lungo devi aggiungere lo Ldopo di esso. Il tuo numero dovrebbe quindi assomigliare a questo 600851475143L.

Poiché alcuni caratteri rendono difficile distinguere tra loro "1" e "l" minuscola, è necessario utilizzare sempre la "L" maiuscola.



4

In fase di compilazione il numero "600851475143" è rappresentato in numero intero a 32 bit, prova invece il letterale lungo alla fine del numero per superare questo problema.


3

A parte tutte le altre risposte, quello che puoi fare è:

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

per esempio :

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

1

Oppure puoi dichiarare il numero di input lungo e poi lasciare che esegua il codice 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;
        }
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.