Add interest per plot with Bigdecimal?

Asked

Viewed 495 times

2

I am creating a system where I need to calculate the interest and add the installments of a loan. For this, I am using BigDecimal and I’m unable to perform the mathematical operation following the formula of rendering calculations. How to do this?

I’m trying like this:

private void calcular(){
        /**
         * formula
         * PMT = PV. i
         *          ----
         *          1 - (1 + i)^-n
         * 
         */
        BigDecimal total = new BigDecimal(0);
        BigDecimal pmt = new BigDecimal(0);
        BigDecimal valorVeiculo = ValorBigDecimal.getValor(txtParcela.getText()); 
        Integer parcela = Integer.parseInt(txtParcela.getText());
        BigDecimal entrada = valorEntrada();
        BigDecimal juros = ValorBigDecimal.getValor(txtJuros.getText()).divide(new BigDecimal(100));

        //valor do veiculo - valor entrada
        total = total.add(valorVeiculo).subtract(entrada);

        //calcula prestacao
        pmt = pmt.add(total).multiply(juros.divide(new BigDecimal(1).subtract(new BigDecimal(1).add(juros).pow(parcela))));
        pmt = pmt.setScale(2, RoundingMode.HALF_EVEN);
        System.out.println(pmt);


    }

Canvas

inserir a descrição da imagem aqui

  • And what is your doubt?

  • @mustache doubt eh I believe I’m doing wrong because I can’t get the result. So I asked how to do ?

  • Fernando, you have the mathematical calculus?

  • This is the formula : PMT = PV. i / 1 - (1 + i) -n ?

  • What is PMT, PV, i, and n? Try to put in your question a caption!

  • @seamusd for what I researched there is a formula for this, that eh I left enunciated in the method calcular(), is what I’m trying to do. I tried to follow this video: https://www.youtube.com/watch?v=P6V2QOv1qLE

  • Fernando, edit the question and inform that you need to do this using Bigdecimal, because using primitives, you may have some problems accurately. Thus, you make evident the need of Bigdecimal.

  • 2

    @diegofm I think a good tip, even if it is installment, involves money, it is implied that can not be double, and his code already showed that it was BigDecimal from the beginning. Staff need to read the question before answering.

Show 3 more comments

2 answers

3


Solved. I followed 2 formulas to get to the result the first formula PMT = PV * i / 1 - (1 + i)^-n and the second formula PMT = PV / (1 + i)^n - 1 / (1 + i)^n * i. With the first formula I could not make work, soh I was successful using the second formula which was as below.

private void calcular(){
        /**
         * formulas
         * F1 -> PMT = PV * i / 1 - (1 + i)^-n (nao funciona)       
         * F2 -> PMT = PV / (1 + i)^n - 1 / (1 + i)^n * i (funciona 100%)
         */
        BigDecimal total = new BigDecimal(0);
        BigDecimal diferenca = new BigDecimal(0);
        BigDecimal pv = ValorBigDecimal.getValor(txtValorVeiculo.getText());
        BigDecimal juros = ValorBigDecimal.getValor(txtJuros.getText()).divide(new BigDecimal(100));
        BigDecimal entrada = getValorEntrada();
        Integer parcelas = Integer.parseInt(txtParcela.getText());
        BigDecimal taxa = new BigDecimal(0);
        BigDecimal t1 = new BigDecimal(0);
        BigDecimal t2 = new BigDecimal(0);

        //calcula diferenca entre valor do veiculo e a entrada        
        diferenca = diferenca.add(pv).subtract(entrada);
        //(1 + i)^n - 1 
        t1 = BigDecimal.ONE.add(juros).pow(parcelas).subtract(BigDecimal.ONE);
        //(1 + i)^n * i
        t2 = BigDecimal.ONE.add(juros).pow(parcelas).multiply(juros);
        //(1 + i)^n - 1 / (1 + i)^n * i -> t1 / t2
        taxa = t1.divide(t2, 2, RoundingMode.HALF_UP);
        total = diferenca.divide(taxa, 2, RoundingMode.HALF_UP);

        System.out.println(t1);
        System.out.println(t2);
        System.out.println(taxa);
        System.out.println(total);        

    }
  • You can use BigDecimal.ZERO instead of new BigDecimal(0).

2

Well, I made this class to solve your problem:

public final class PrecoComJuros {
    private final BigDecimal valorBase;
    private final BigDecimal valorParcelado; // pv
    private final BigDecimal entrada;
    private final int numeroParcelas;
    private final BigDecimal taxaJuros;
    private final BigDecimal valorParcela;
    private final BigDecimal valorTotal; // pmt
    private final BigDecimal valorJuros;

    public PrecoComJuros(BigDecimal valorBase, BigDecimal entrada, int numeroParcelas, BigDecimal taxaJuros) {
        if (numeroParcelas <= 0) throw new IllegalArgumentException();
        if (taxaJuros.compareTo(BigDecimal.ZERO) < 0) throw new IllegalArgumentException();
        this.valorBase = valorBase;
        this.entrada = entrada;
        this.numeroParcelas = numeroParcelas;
        this.taxaJuros = taxaJuros;
        BigDecimal juros = taxaJuros.divide(CEM); // i
        this.valorParcelado = valorBase.subtract(entrada);
        if (taxaJuros.compareTo(BigDecimal.ZERO) == 0) {
            this.valorParcela = valorParcelado.divide(BigDecimal.valueOf(numeroParcelas), 2, RoundingMode.HALF_EVEN);
        } else {
            BigDecimal potencia = juros.add(BigDecimal.ONE).pow(numeroParcelas);
            BigDecimal denominador = BigDecimal.ONE.subtract(BigDecimal.ONE.divide(potencia, 20, RoundingMode.HALF_EVEN));
            this.valorParcela = valorParcelado.multiply(juros).divide(denominador, 2, RoundingMode.HALF_EVEN);
        }
        this.valorJuros = valorParcela.multiply(BigDecimal.valueOf(numeroParcelas));
        this.valorTotal = entrada.add(valorJuros);
    }

    public BigDecimal getValorBase() {
        return valorBase;
    }

    public BigDecimal getValorParcelado() {
        return valorParcelado;
    }

    public BigDecimal getEntrada() {
        return entrada;
    }

    public int getNumeroParcelas() {
        return numeroParcelas;
    }

    public BigDecimal getTaxaJuros() {
        return taxaJuros;
    }

    public BigDecimal getValorParcela() {
        return valorParcela;
    }

    public BigDecimal getValorTotal() {
        return valorTotal;
    }

    public BigDecimal getValorJuros() {
        return valorJuros;
    }
}

Here is her test:

public static void main(String[] args) {
    System.out.println(Arrays.toString(" : : ".split(":")));
    PrecoComJuros p = new PrecoComJuros(BigDecimal.valueOf(30_000), BigDecimal.valueOf(10_000), 24, BigDecimal.valueOf(5));
    System.out.println("Valor da parcela: " + p.getValorParcela());
    System.out.println("Juros total: " + p.getValorJuros());
    System.out.println("Valor total: " + p.getValorTotal());
}

Some comments on implementation:

  • Pass a negative exponent to the method pow makes an exception. The solution to this is to note that a^(-b) = 1 / (a^b), and therefore we can eliminate the need to use a negative exponent.

  • There is a special treatment for the case of zero interest rate. If there was no such treatment, a division by zero would occur.

  • Values with number of installments equal to zero or negative or with negative interest rates are rejected.

  • The plot value is calculated with cents (2 digits after the comma). Intermediate calculations, however use up to 20 houses after the comma.

  • Very good answer! + 1 more than deserved :)

Browser other questions tagged

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