Financial calculation with decimal large numbers

Asked

Viewed 692 times

1

I had created the code below for financing calculation. I converted mathematics to Java code, I used variables of the type double.

But the result was Infinity, I’m trying to use the BigDecimal, I am lost, the lines that present be with error have the comments indicating this.

BigDecimal pv = new BigDecimal(txtValor.getText());
BigDecimal taxa = new BigDecimal(txtTaxa.getText());
int prazo = Integer.parseInt(txtPrazo.getText());


double porcento = taxa / 100; // Erro aqui

for(int parcela=1; parcela <= pv; parcela++){ // Erro aqui

    double j1 = 1+porcento;
    double j2;
    j2 = Math.pow(j1, prazo);
    double j3 = 1-j2;
    double j4 = taxa / j3; // Erro aqui
    double j5 = pv * j4; // Erro aqui

    lP1.setText(Double.toString(parcela));
    lV1.setText(Double.toString(j5));
  • pv means present value and no number of plots. Within the calculation, you have to use exponentiation with the portion number, or else all the plots would be equal and that’s not the purpose. See more in my answer downstairs.

3 answers

2

To work with BigDecimal, well, you need to use BigDecimal.

Operations with BigDecimal are using the methods that the class itself has

  • add() to add
  • substract() to subtract
  • divide() to divide
  • multiply() to multiply

And you necessarily need to pass a Bigdecimal as value

BigDecimal pv = new BigDecimal("200.0");
BigDecimal taxa = new BigDecimal("10");
int prazo = 10;


BigDecimal porcento = taxa.divide(new BigDecimal("100"));

for(int parcela=1; parcela <= pv.intValue(); parcela++){

    BigDecimal j1 = porcento.add(new BigDecimal("1"));
    BigDecimal j2 = j1.pow(prazo);
    BigDecimal j3 = new BigDecimal("1").subtract(j2);
    BigDecimal j4 = taxa.divide(j3);
    BigDecimal j5 = pv.multiply(j4);

    lP1.setText(Double.toString(parcela));
    lV1.setText(Double.toString(j5.doubleValue()));
}

And of course, you can extract values inteiros and doubles of a BigDecimal using the methods

  • intValue() to extract value inteiro
  • doubleValue() to extract value double // in this case, this is what was used in the code I passed to be able to lV1
  • Use BigDecimal.ONE, BigDecimal.TEN, new BigDecimal(100) and new BigDecimal(200).

  • In the j3 you reversed the order of the numbers in the subtraction.

  • Why do you declare the veritable decimal with the 200? You don’t use it for anything and it wasn’t in the original code either.

  • the new BigDecimal(200) was unintentionally, I’ve already withdrawn and tried to do the most didactic possible.

  • Climb what Victor said when using BigDecimal.ONE: if these accounts are frequent things, it is better to use a single variable than to keep creating more and more variables with the new. This will decrease the Footprint memory application. I would even BigDecimal.TEN.movePointRigth(1) to represent the 100, aiming to take away my responsibility to allocate space to the 100, allowing Java to use some buffer occasional

  • Yes, of course! This code could be greatly improved. But I tried to be didactic when it comes to using the Bigdecimal class.

Show 1 more comment

1


First, I wonder if the calculation is correct, after all, you are not using the variable parcela in it. In addition pv means present value, and no number of plots, so it makes no sense to iterate the number of plots until the pv. It makes sense to iterate to the prazo if this corresponds to the number of plots. Within the calculation of each plot, raising a variable to the exponent given by the present value also makes no sense, but the number of the plot yes. This is why your calculation does not work and results in Infinity.

Then you use the methods of BigDecimal to do the math. In particular, the methods to be used are the add(BigDecimal), the subtract(BigDecimal), the multiply(BigDecimal), the divide(BigDecimal) and the pow(int).

You can also use the builder who receives a int to convert a int in a BigDecimal. When the value to be converted is 0, 1 or 10, you can use the static fields BigDecimal.ZERO, BigDecimal.ONE and BigDecimal.TEN.

Here’s what the code looks like:

private static final BigDecimal CEM = new BigDecimal(100);

// ...

BigDecimal bigPv = new BigDecimal(txtValor.getText());
BigDecimal taxa = new BigDecimal(txtTaxa.getText());
int prazo = Integer.parseInt(txtPrazo.getText());

BigDecimal porcento = taxa.divide(CEM);
BigDecimal j1 = porcento.add(BigDecimal.ONE);

for (int parcela = 1; parcela <= prazo; parcela++) {
    BigDecimal j2 = j1.pow(parcela);
    BigDecimal j3 = BigDecimal.ONE.subtract(j2);
    BigDecimal j4 = taxa.divide(j3);
    BigDecimal j5 = j4.multiply(pv);

    lP1.setText(String.valueOf(parcela));
    lV1.setText(j5.toPlainString());

In the end, you don’t need to convert the BigDecimal for Double to then put in the lV1, just use the method toPlainString(). It is important not to confuse it with the toString() and the toEngineeringString() that have a slightly different functioning.

Notice that I kept the creation of CEM and the j1 outside the for for the sake of performance, so that it is not necessary to always recreate the same BigDecimals. The j1 does not depend on the value of parcela, only of the da taxa, soon can stay out of the for. In the case of CEM, as she is a constant, I put as static.

I also note that the lP1.setText and the lV1.setText within the for should not be what you want, because only the last computed value will remain.

Another however is that you decided to use BigDecimal because I was getting Infinity as a result. It turns out that the real problem is that its calculation form was wrong (as I explained in the first paragraph). Use BigDecimal would not solve the problem of using the wrong formula. Thus, you could re-use double, although I do not recommend, because BigDecimal is recommended for financial calculations.

Finally, I recommend you review the above calculation, because although I noticed a mistake in your way of performing the calculation, it does not mean that there are no other errors.

-1

Thank you all, as I had run out of net I tried to solve the problem myself and I managed in a simple way. I fixed the logic of my code.

Your answers taught me to understand Bigdecimal, thank you very much. Henrique Santiago & Victor Stafusa

Follow the code as it was in case anyone wants to see

double pv = Double.parseDouble(txtValor.getText());
double taxa = Double.parseDouble(txtTaxa.getText());
double prazo = Double.parseDouble(txtPrazo.getText());


double porcento = taxa / 100;

double j1 = 1 + porcento;
double j2 = Math.pow(j1, prazo);
double j3 = 1 / j2;
double j4 = 1 - j3;
double j5 = porcento / j4;
double j6 = pv * j5;
lV1.setText(Double.toString(j6));

double valorTotal = j6 * prazo;
lVt.setText(Double.toString(valorTotal));

double totalJuros = valorTotal - pv;
lVtJ.setText(Double.toString(totalJuros));

Browser other questions tagged

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