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


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 .


¿Esto en Java de Android 17 (similar a JDK6)?
— Ben Leggiero
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.