ArithmeticException: “Expansión decimal sin terminación; no hay un resultado decimal representable exacto “

¿Por qué el siguiente código aumenta la excepción que se muestra a continuación?

BigDecimal a = new BigDecimal("1.6"); BigDecimal b = new BigDecimal("9.2"); a.divide(b) // results in the following exception. 

 java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. 

De los documentos de Java 5 (documentos de Java 8 aquí ):

Cuando se proporciona un objeto MathContext con una configuración de precisión de 0 (por ejemplo, MathContext.UNLIMITED), las operaciones aritméticas son exactas, al igual que los métodos aritméticos que no toman ningún objeto MathContext. (Este es el único comportamiento admitido en versiones anteriores a 5.)

Como corolario de la computación del resultado exacto, la configuración del modo de redondeo de un objeto MathContext con una configuración de precisión de 0 no se utiliza y, por lo tanto, es irrelevante. En el caso de dividir, el cociente exacto podría tener una expansión decimal infinitamente larga; por ejemplo, 1 dividido por 3.

Si el cociente tiene una expansión decimal no determinante y la operación se especifica para devolver un resultado exacto, se lanza una ArithmeticException. De lo contrario, se devuelve el resultado exacto de la división, como se hizo para otras operaciones.

Para solucionarlo, debes hacer algo como esto :

 a.divide(b, 2, RoundingMode.HALF_UP) where 2 is precision and RoundingMode.HALF_UP is rounding mode 

Más detalles: http://jaydeepm.wordpress.com/2009/06/04/bigdecimal-and-non-terminating-decimal-expansion-error/

Porque no especificas una precisión y un modo de redondeo. BigDecimal se queja de que podría usar 10, 20, 5000 o decimales infinitos, y aún así no podría darle una representación exacta del número. Entonces, en lugar de darte un BigDecimal incorrecto, solo te lloriquea.

Sin embargo, si proporciona un RoundingMode y una precisión, podrá convertir (por ejemplo, 1.333333333-infinito a algo así como 1.3333 … pero usted, como progtwigdor, debe decirle con qué precisión está “contento” ‘.

Tu puedes hacer

 a.divide(b, MathContext.DECIMAL128) 

Puede elegir la cantidad de bits que desee ya sea 32,64,128.

Mira este enlace:

http://edelstein.pebbles.cs.cmu.edu/jadeite/main.php?api=java6&state=class&package=java.math&class=MathContext

Para solucionar un problema así, he usado el código siguiente

 a.divide(b, 2, RoundingMode.HALF_EVEN) 

2 es precisión. Ahora el problema fue resuelto.

Tuve el mismo problema porque mi línea de código era:

 txtTotalInvoice.setText(var1.divide(var2).doubleValue() + ""); 

Cambio a esto, leyendo la respuesta anterior, porque no estaba escribiendo precisión decimal:

 txtTotalInvoice.setText(var1.divide(var2,4, RoundingMode.HALF_UP).doubleValue() + ""); 

4 es Decimal Precion

Y RoundingMode son constantes de Enum, puede elegir cualquiera de estos UP, DOWN, CEILING, FLOOR, HALF_DOWN, HALF_EVEN, HALF_UP

En este caso HALF_UP, tendrá este resultado:

 2.4 = 2 2.5 = 3 2.7 = 3 

Puede consultar la información de RoundingMode aquí: http://www.javabeat.net/precise-rounding-of-decimals-using-rounding-mode-enumeration/

Respuesta para BigDecimal arroja ArithmeticException

 public static void main(String[] args) { int age = 30; BigDecimal retireMentFund = new BigDecimal("10000.00"); retireMentFund.setScale(2,BigDecimal.ROUND_HALF_UP); BigDecimal yearsInRetirement = new BigDecimal("20.00"); String name = " Dennis"; for ( int i = age; i <=65; i++){ recalculate(retireMentFund,new BigDecimal("0.10")); } BigDecimal monthlyPension = retireMentFund.divide( yearsInRetirement.divide(new BigDecimal("12"), new MathContext(2, RoundingMode.CEILING)), new MathContext(2, RoundingMode.CEILING)); System.out.println(name+ " will have £" + monthlyPension +" per month for retirement"); } public static void recalculate (BigDecimal fundAmount, BigDecimal rate){ fundAmount.multiply(rate.add(new BigDecimal("1.00"))); } 

Agregue el objeto MathContext en su llamada de método de división y ajuste la precisión y el modo de redondeo. Esto debería solucionar tu problema

Es porque el Bigdecimal no tiene pérdidas, y si divide 1/3 por ejemplo, dará como resultado un decimal que se repite hasta el infinito. 0.33333333 … teóricamente si multiplicas de nuevo, recibes el resultado exacto. Pero, un número infinito generará stack over flow y en este caso se lanza la excepción.

Mi solución:

  try { result = n1.divide(n2); } catch (ArithmeticException e){ Log.d("Error bigdecimal", e.toString()); result = (n1.doubleValue() / n2.doubleValue()); }; 

en este caso, su resultado no se reducirá al redondear

Su progtwig no sabe qué precisión usar para los números decimales para que arroje:

 java.lang.ArithmeticException: Non-terminating decimal expansion 

Solución para eludir la excepción:

 MathContext precision = new MathContext(int setPrecisionYouWant); // example 2 BigDecimal a = new BigDecimal("1.6",precision); BigDecimal b = new BigDecimal("9.2",precision); a.divide(b) // result = 0.17 

Es una cuestión de redondear el resultado, la solución para mí es la siguiente.

 divider.divide(dividend,RoundingMode.HALF_UP); 
    Intereting Posts