Estaba intentando rastrear un comportamiento Java muy extraño. Tengo una fórmula que implica un doble, pero está "garantizada" para dar una respuesta entera, específicamente, un entero de 32 bits sin signo (que, por desgracia, Java no funciona bien). Desafortunadamente, mis respuestas fueron a veces incorrectas.¿Los moldes primitivos de tipo entero de Java están "limitados" a MAX_INT del tipo de fundición?
Finalmente encontré el problema, pero el comportamiento es todavía muy extraño para mí: un elenco double
directamente a un int
parece estar limitado a un máximo MAX_INT
para un entero con signo, mientras que un elenco double
a un long
que es luego emitir a int
me da la respuesta esperada (-1; el INT MAXIMO de un entero de 32 bits sin signo representado como un entero de 32 bits con signo).
escribí un pequeño programa de prueba:
public static void main(String[] args) {
// This is the Max Int for a 32-bit unsigned integer
double maxUIntAsDouble = 4294967295.00;
long maxUintFromDoubleAsLong = (long)maxUIntAsDouble;
long maxUintFromDoubleAsInt = (int)maxUIntAsDouble;
int formulaTest = (int) (maxUintFromDoubleAsLong * 1.0);
int testFormulaeWithDoubleCast = (int)((long) (maxUintFromDoubleAsLong * 1.0));
// This is a more-or-less random "big number"
long longUnderTest = 4123456789L;
// Max int for a 32-bit unsigned integer
long longUnderTest2 = 4294967295L;
int intFromLong = (int) longUnderTest;
int intFromLong2 = (int) longUnderTest2;
System.out.println("Long is: " + longUnderTest);
System.out.println("Translated to Int is:" + intFromLong);
System.out.println("Long 2 is: " + longUnderTest2);
System.out.println("Translated to Int is:" + intFromLong2);
System.out.println("Max UInt as Double: " + maxUIntAsDouble);
System.out.println("Max UInt from Double to Long: " + maxUintFromDoubleAsLong);
System.out.println("Max UInt from Double to Int: " + maxUintFromDoubleAsInt);
System.out.println("Formula test: " + formulaTest);
System.out.println("Formula Test with Double Cast: " + testFormulaeWithDoubleCast);
}
Cuando ejecuto este pequeño programa me sale:
Long is: 4123456789
Translated to Int is:-171510507
Long 2 is: 4294967295
Translated to Int is:-1
Max UInt as Double: 4.294967295E9
Max UInt from Double to Long: 4294967295
Max UInt from Double to Int: 2147483647
// MAX INT for an unsigned int
Formula test: 2147483647
// Binary: all 1s, which is what I expected
Formula Test with Double Cast: -1
Las dos últimas líneas son las que yo estoy tratando de entender. El doble elenco me da el "-1" esperado; pero el elenco directo me da MAX_INT para un entero con signo de 32 bits. Viniendo de un fondo de C++, entendería si me da un "número impar" en lugar del -1 esperado (también conocido como "ingenuo de fundición"), pero esto me tiene perplejo.
Así, a la pregunta entonces: este comportamiento es "esperado" en Java (por ejemplo, cualquier double
fundido directamente a un int
será "tope" a MAX_INT
)? ¿El casting hace esto para cualquier tipo inesperado? Esperaría que sea similar para short
y byte
, por ejemplo; pero, ¿cuál es el 'comportamiento esperado' al lanzar un doble grande para flotar?
Gracias!
Conocía la falta de "unsigned" en Java (una de las cosas que hace que Java sea tan doloroso cuando se trabaja con protocolos orientados a bits), pero la mayor parte del resto es completamente nueva. Definitivamente no habría esperado ese comportamiento de "corto" y "byte". Gracias. :RE –