Mensaje de error "Número entero demasiado grande" para 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();
    }
}

Cuando se ejecuta el código anterior, produce un error en la línea obj.function(600851475143);. ¿Por qué?

usuario446654
fuente
1
Además, ¿no hay diferencia entre "l" y "L"?
user446654
@ user446654: No, la hay. Este último es más legible. Lea "Java Puzzler" para esto.
Adeel Ansari
@ user446654: evolucionando los pensamientos de @Thilo sobre un posible límite de memoria excedido Quiero agregar mis 2 monedas: has elegido un algoritmo realmente malo para buscar todos los divisores de un número si quieres operar con números tan grandes como en tu ejemplo. Algo basado en programación dinámica probablemente funcionaría mejor. Google en eso para obtener más resultados.
Roman
1
Se agregó la etiqueta PE, Proyecto Euler # 3
st0le
@ st0le: En mi humilde opinión, la pregunta definitivamente no es sobre la solución del problema original, y lo que vemos tampoco es una solución.
Roman

Respuestas:

200

600851475143no se puede representar como un entero de 32 bits (tipo int). Puede representarse como un entero de 64 bits (tipo long). los literales largos en Java terminan con una "L":600851475143L

Yuliy
fuente
71

Anexar sufijos L: 23423429L.

De forma predeterminada, Java interpreta todos los literales numéricos como valores enteros de 32 bits. Si desea especificar explícitamente que esto es algo más grande que un entero de 32 bits, debe usar el sufijo Lpara valores largos.

romano
fuente
Para aquellos que buscan una explicación más completa de por qué recibe este mensaje de error incluso después de cambiar el tipo de variable a long, lea esto: stackoverflow.com/a/8924925/293280
Joshua Pinter
29

Necesitas usar un literal largo:

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

Pero esperaría que esa función se quede sin memoria (o tiempo) ...

Thilo
fuente
17
se considera una mejor práctica hacer las lmayúsculas, de modo que se pueda distinguir fácilmente de1
Bozho
2
@Bozho: De acuerdo. Pero tengo experiencia en Perl. Codifico "solo escritura" :-)
Thilo
Use "L" en lugar de "l"
Kevin V
13

El compilador de Java intenta interpretar 600851475143 como un valor constante de tipo int por defecto. Esto provoca un error ya que 600851475143 no se puede representar con un int.

Para decirle al compilador que desea que el número se interprete como largo, debe agregar lo Ldespués. Su número debería verse así 600851475143L.

Dado que algunas fuentes dificultan la distinción entre "1" y "l" minúscula, siempre debe utilizar la "L" mayúscula.

josefx
fuente
6

Necesita 40 bits para representar el literal entero 600851475143. Sin embargo, en Java, el valor entero máximo es 2 ^ 31-1 (es decir, los enteros son 32 bits, consulte http://download.oracle.com/javase/1.4.2/docs /api/java/lang/Integer.html ).

Esto no tiene nada que ver function. Intente usar un literal entero largo en su lugar (como se sugiere en las otras respuestas).

Andre Holzner
fuente
4

En el momento de la compilación, el número "600851475143" se representa en un entero de 32 bits, pruebe con un literal largo al final de su número para superar este problema.

JVM
fuente
3

Aparte de todas las otras respuestas, lo que puede hacer es:

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

por ejemplo :

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

O puede declarar el número de entrada tan largo y luego dejar que haga el código 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
fuente