Message d'erreur "Nombre entier trop grand" pour 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();
    }
}

Lorsque le code ci-dessus est exécuté, il produit une erreur sur la ligne obj.function(600851475143); . Pourquoi?

user446654
la source
1
il n'y a pas non plus de différence entre "l" et "L"?
user446654
@ user446654: Non, il y en a. Ce dernier est plus lisible. Lisez «Java Puzzler» pour cela.
Adeel Ansari
@ user446654: évolution des réflexions de @Thilo sur le dépassement possible de la limite de mémoire Je veux ajouter mes 2 pièces: vous avez choisi un très très mauvais algorithme pour rechercher tous les diviseurs d'un nombre si vous voulez fonctionner avec des nombres aussi grands que dans votre exemple. Quelque chose basé sur une programmation dynamique fonctionnerait probablement mieux. Google à ce sujet pour d'autres résultats.
Roman
1
Ajout de la balise PE, Project Euler # 3
st0le
@ st0le: à mon humble avis, la question ne concerne certainement pas la solution originale du problème, et ce que nous voyons n'est pas non plus une solution.
Roman

Réponses:

200

600851475143ne peut pas être représenté sous la forme d'un entier 32 bits (type int). Il peut être représenté sous la forme d'un entier 64 bits (type long). les longs littéraux en Java se terminent par un "L":600851475143L

Yuliy
la source
71

Append suffixe L: 23423429L.

Par défaut, java interprète tous les littéraux numériques comme des valeurs entières 32 bits. Si vous souhaitez spécifier explicitement qu'il s'agit de quelque chose de plus grand qu'un entier 32 bits, vous devez utiliser le suffixe Lpour les valeurs longues.

romain
la source
Pour ceux qui recherchent une explication plus approfondie de la raison pour laquelle vous obtenez ce message d'erreur même après avoir changé le type de variable en long, lisez ceci: stackoverflow.com/a/8924925/293280
Joshua Pinter
29

Vous devez utiliser un long littéral:

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

Mais je m'attendrais à ce que cette fonction manque de mémoire (ou de temps) ...

Thilo
la source
17
il est considéré comme une meilleure pratique de faire les lmajuscules, de sorte qu'il soit facilement distinguable de1
Bozho
2
@Bozho: D'accord. Mais j'ai une formation Perl. Je code "écriture seule" :-)
Thilo
Utilisez "L" au lieu de "l"
Kevin V
13

Le compilateur java essaie d'interpréter 600851475143 comme une valeur constante de type int par défaut. Cela provoque une erreur car 600851475143 ne peut pas être représenté avec un int.

Pour indiquer au compilateur que vous voulez que le nombre d'interprétations soit long, vous devez ajouter l'un lou l' autre ou Laprès. Votre numéro devrait alors ressembler à ceci 600851475143L.

Étant donné que certaines polices rendent difficile la distinction entre "1" et "l" minuscule, vous devez toujours utiliser la majuscule "L".

josefx
la source
6

Vous avez besoin de 40 bits pour représenter le littéral entier 600851475143. En Java, la valeur entière maximale est cependant 2 ^ 31-1 (c'est-à-dire que les entiers sont de 32 bits, voir http://download.oracle.com/javase/1.4.2/docs /api/java/lang/Integer.html ).

Cela n'a rien à voir avec function. Essayez plutôt d'utiliser un long littéral entier (comme suggéré dans les autres réponses).

André Holzner
la source
4

Au moment de la compilation, le nombre «600851475143» est représenté en entier 32 bits, essayez plutôt un long littéral à la fin de votre nombre pour surmonter ce problème.

JVM
la source
3

En dehors de toutes les autres réponses, ce que vous pouvez faire est:

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

par exemple :

obj.function(Long.parseLong("600851475143"));
Anand Undavia
la source
1

Ou, vous pouvez déclarer le nombre d'entrée aussi longtemps, puis le laisser faire le code 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;
        }
    }
}
Milen.Jeremic
la source