Miscalculation

Asked

Viewed 103 times

0

Hello, I am with a project of a consortium calculator that is showing error. It receives from the user the following data:

  • Value of the consortium
  • Amount of months
  • % from the reserve fund
  • % of the administrative fee

After that he calculates the value of the monthly installment.

My problem is this: If I put the amount of months 10 works if put 15 already gives error.

Follows the code:

BigDecimal cota = new BigDecimal(jTextField1.getText());
BigDecimal prazo = new BigDecimal(jTextField2.getText());
BigDecimal reserva = new BigDecimal(jTextField3.getText());
BigDecimal adm = new BigDecimal(jTextField4.getText());

DecimalFormat decimal = new DecimalFormat("0.##");

//Calculo Fundo Comum
BigDecimal pc = new BigDecimal("100");
BigDecimal percentualMensal = pc.divide(prazo);
BigDecimal parcelaMensal = percentualMensal.multiply(cota);
BigDecimal parcelaMensal1 = parcelaMensal.divide(pc);

//Calculo Taxa Administrativa
BigDecimal a1 = adm.divide(prazo);
BigDecimal parcelaAdm = a1.multiply(cota);
BigDecimal parcelaAdm1 = parcelaAdm.divide(pc);

//Calculo Fundo Reserva
BigDecimal r1 = reserva.divide(prazo);
BigDecimal parcelaReserva = cota.multiply(r1);
BigDecimal parcelaReserva1 = parcelaReserva.divide(pc);

BigDecimal calculo = parcelaMensal1.add(parcelaAdm1.add(parcelaReserva1));

String a = decimal.format(calculo);

jLabel5.setText("Valor: "+a);
  • 1

    But what’s the mistake?

  • pc.divide(prazo); - And if the division gives a periodic tithe, what should it do? The way it is, it will give ArithmeticException.

  • 2

    With 10 it works because 10 is divisor 100. 15 is not divisor 100, so it will give this exception. You have to say what you want to do when the division gives a periodic tithe.

1 answer

1


The problem has already been indicated by @Vitorstafusa in the comments, which is the fact that the division results in an infinite periodic decimation, in the method divide.

If you consider a 15-month deadline, the division you’re doing is 100/15 that gives 6.6666666 infinitely.

Example of code problem (15 forced):

BigDecimal v1 = new BigDecimal(100);
BigDecimal v2 = new BigDecimal(15);     
BigDecimal v3 = v1.divide(v2);

System.out.println(v3);

That generates an exception in the method divide:

java.lang.Arithmeticexception: Non-terminating decimal Expansion; no representable decimal Exact result.

See the exception occurring in Ideone

Solution

The solution to this problem is actually simple. You just need to change your call to the method divide indicating in how many decimal places the result and rounding mode:

BigDecimal v3 = v1.divide(v2, 4, RoundingMode.HALF_UP);
//casas decimais--------------^ ,  ^-------- modo de arredondamento

See also this example in Ideone

You have at your disposal 3 rounding modes:

  • HALF_DOWN
  • HALF_UP
  • HALF_EVEN
  • HALF_EVEN is called bank rounding. Statistically, it is what generates the least errors in a large set of operations. Due to this nature of generating few errors, it is used by bankers to make accounts

  • 1

    @Jeffersonquesado Yes it makes sense because it does not always go to the same side, so with a large amount of calculations the error is lower, statistically speaking

Browser other questions tagged

You are not signed in. Login or sign up in order to post.