Error de desbordamiento posible de Java BigDecimal

78

Estaba probando condiciones de límite en algún código que involucraba a BigDecimal, y noté que cuando BigDecimalse inicializa a con String, "1e2147483647"se comporta inesperadamente. Parece tener un valor entre 0y 1e-2147483647. Cuando intento llamar intValue(), obtengo un NegativeArraySizeException. Debo notar que 2147483647es el valor máximo de un número entero en mi sistema. ¿Estoy haciendo algo mal o es un problema BigDecimal?

BigDecimal test = new BigDecimal("1e2147483647");

test.compareTo(new BigDecimal(0));  //Returns 1
test.compareTo(new BigDecimal("1e-2147483647"));  //Returns -1
test.intValue();  //Throws NegativeArraySizeException
DJMatch3000
fuente
Gracias, no había visto esa pregunta. Me sorprendió que no arrojara una NumberFormatException desde el constructor como lo hace para un número un dígito más grande.
DJMatch3000
Esto es más una sugerencia que saber, pero 1e-2147483647es un número bastante grande. Para ser precisos, log_2(10^2147483647) / 8 / 1024^3 = 0.83...debería producir el tamaño mínimo (en Gigabytes) para representar un número tan grande como un entero. ¿Quizás esto sea algún tipo de problema de asignación de memoria?
Turing85
3
@ DJMatch3000: No, su entrada es válida y representable, aunque ese es el máximo exponente que puede representar BigDecimal. Tu error es legítimo.
Louis Wasserman

Respuestas:

87

No, parece que tienes un error legítimo. El error se presenta en JDK7 pero corregido en JDK8. Sus valores se pueden representar correctamente como BigDecimals, y deberían comportarse correctamente, pero no lo hacen.

El rastreo a través del código fuente deBigDecimal , en la línea 2585, this.precision()es 1 y this.scalees -2147483647. this.precision() - this.scalepor lo tanto, se desborda y el siguiente desbordamiento no se maneja correctamente.

Este error se ha corregido en JDK8 haciendo la resta en longaritmética .

Louis Wasserman
fuente
¿Esto en Java de Android 17 (similar a JDK6)?
Ben Leggiero