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é?


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


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.


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) ...


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.



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.


3

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

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

por ejemplo :

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

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;
        }
    }
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.