El xyz literal de tipo int está fuera de rango

90

Estoy trabajando con tipos de datos en este momento en Java, y si lo he entendido correctamente, el tipo longacepta un valor entre los rangos de -9,223,372,036,854,775,808 a +9,223,372,036,854,775,807. Ahora, como puede ver a continuación, he creado una longvariable llamada testLong, aunque cuando inserto 9223372036854775807 como valor, aparece un error que indica:

El literal 9223372036854775807 del tipo int está fuera de rango.

No sé por qué se refiere al longtipo de datos como int.

¿Alguien tiene alguna idea?

Código:

char testChar = 01;
byte testByte = -128;
int testInt = -2147483648;
short testShort = -32768;
long testLong = 9223372036854775807;
float testFoat;
double testDouble = 4.940656458412;
boolean testBool = true;
Mathew Donnan
fuente
Por cierto: ¿qué compilador estás usando? Tanto Eclipse como el compilador Sun JDK dan mensajes de error diferentes (en mi opinión, mejores) para este problema.
Joachim Sauer

Respuestas:

196

Agregue una mayúscula Lal final:

long value = 9223372036854775807L;

De lo contrario, el compilador intentará analizar el literal como un int, de ahí el mensaje de error

Lukas Eder
fuente
4
Está en las especificaciones del lenguaje Java. Encuentre el texto completo aquí
Lukas Eder
@Lukas, valor largo = 00000077029062100L; me da el mismo error, y tiene menos de 19 dígitos. cualquier idea de por qué arroja "El literal 0000007702062100L de tipo largo está fuera de rango"
Santossh Kumhar
1
@SantosshKumhar: Es un literal octal , que no puede contener dígitos 8o 9. Quite los ceros iniciales.
Lukas Eder
51

No sé por qué se refiere al tipo de datos largo como int

No lo es. Debe aprender a confiar en los mensajes del compilador (especialmente cuando son de compiladores sanos y modernos y no de compiladores antiguos de C / C ++). Si bien el idioma que hablan puede ser difícil de descifrar en ocasiones, generalmente no te están mintiendo.

Veámoslo de nuevo:

El literal de int 9223372036854775807 está fuera de rango.

Tenga en cuenta que no menciona su variable testLongo el tipo en longninguna parte, por lo que no se trata de la inicialización. El problema parece ocurrir en algún otro momento.

Ahora investiguemos algunas de las partes del mensaje:

  • intnos dice que quiere tratar algo como un intvalor (¡que no es lo que querías!)
  • "fuera de rango" es bastante claro: algo no está dentro del rango esperado (probablemente el de int)
  • "El literal": eso es interesante: ¿qué es un literal?

Dejaré la acogedora lista para hablar de literales por un momento: los literales son lugares donde tienes algún valor en tu código. Hay Stringliterales, literales, intliterales, classetc. Cada vez que mencionas un valor explícitamente en tu código, es literal.

Así que no te está molestando por la declaración de la variable, sino por el número en sí, el valor es lo que te molesta.

Puede verificar esto fácilmente utilizando el mismo literal en un contexto donde un long y an intson igualmente aceptables:

System.out.println(9223372036854775807);

PrintStream.println puede tomar cualquiera unaint o unalong (o casi cualquier otra cosa). Entonces ese código debería estar bien, ¿verdad?

No. Bueno, tal vez debería serlo, pero según las reglas no está bien.

El problema es que "algunos dígitos" se define como un intliteral y, por lo tanto, debe estar en el rango definido por int.

Si desea escribir un longliteral, debe hacerlo explícito agregando la L(o minúsculal , pero altamente sugeriría que siempre utilice la variante en mayúsculas, porque es mucho más fácil de leer y más difícil de error para una 1).

Tenga en cuenta que ocurre un problema similar con float(postfix F/f ) y double(postfix D/ d).

Nota al margen: se dará cuenta de que no hay byteo shortliterales y aún puede asignar valores (generalmente intliterales) a bytey shortvariables: eso es posible debido a las reglas especiales en § 5.2 sobre Assignment Converson : permiten la asignación de expresiones constantes de un tipo más grande a byte, short, charo int si los valores están dentro del rango de los tipos.

Joachim Sauer
fuente
3
De dónde sacas el tiempo ;-)
Lukas Eder
3
@Lukas: De vez en cuando escribo estas respuestas con la esperanza de no tener que escribir 300 respuestas más cortas ;-) Además: ayudar a interpretar el mensaje de error (con suerte) significa menos preguntas de "qué significa ese mensaje de error".
Joachim Sauer
su respuesta es muy buena ... sin duda, es por eso que vote a favor, pero edítelo y en la parte superior (al comienzo de su respuesta), simplemente escriba en 1 línea la solución exacta al problema, y ​​luego debajo de su explicación. Porque mucha gente busca una solución rápida en lugar de una explicación profunda
Shirish Herwade
4
Son libres de buscar otras segundas respuestas (la más votada incluso ofrece la solución rápida). Creo que educar a las personas sobre cómo analizar y comprender los mensajes de error es más útil a largo plazo que simplemente hacerlo por ellos. "Dale un pescado a un hombre ..." y todo eso.
Joachim Sauer
Gracias por la nota al margen.
Venkatesh Goud
19

Intenta hacerlo 9223372036854775807L. El Lal final le dice a Java que 9223372036854775807es un long.

jontro
fuente
0

Tuve este problema en el pasado y lo solucioné escribiendo el valor en forma científica. por ejemplo:

double val = 9e300;

fuente
-2
long ak = 34778754226788444L/l;

Ambos usan, pero a la vez solo uno usa L mayúscula o l minúscula.

¿Por qué usar L / l? Porque long es parte del tipo de datos integral.

Akkushwaha
fuente