import java.math.BigDecimal;
import java.math.RoundingMode;

class Calculo {

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

    private static final int PRECISAO_CALCULO = 21;
    private static final int PRECISAO_FINAL = 5;

    private static final BigDecimal DELTA =
            BigDecimal.ONE.divide(BigDecimal.TEN.pow(PRECISAO_FINAL));

    private static final BigDecimal financiamento(int n, BigDecimal j, BigDecimal p) {
        BigDecimal a = BigDecimal.ONE.add(j).pow(n);

        BigDecimal b = BigDecimal.ONE.divide(
                a,
                PRECISAO_CALCULO,
                RoundingMode.HALF_EVEN);

        return BigDecimal.ONE
                .subtract(b)
                .multiply(p)
                .divide(j, PRECISAO_CALCULO, RoundingMode.HALF_EVEN);
    }

    private static final BigDecimal taxaFinanciamento(
            BigDecimal q0,
            int n,
            BigDecimal p)
    {
        BigDecimal j1 = DELTA;
        BigDecimal j2 = BigDecimal.ONE;
        BigDecimal q1 = financiamento(n, j1, p);
        BigDecimal q2 = financiamento(n, j2, p);
        BigDecimal m1 = q1.subtract(q0);
        BigDecimal m2 = q2.subtract(q0);
        if (m1.abs().compareTo(DELTA) <= 0) return j1;
        if (m2.abs().compareTo(DELTA) <= 0) return j2;
        for (int i = 0; i < 50; i++) {
            if (m1.signum() == m2.signum()) {
                throw new ArithmeticException("Fora do intervalo"
                        + ": q1=[" + q1 + "], j1=[" + j1 + "], m1=[" + m1 + "]"
                        + ", q2=[" + q2 + "], j2=[" + j2 + "], m2=[" + m2 + "]"
                        + ", i=" + i);
            }
            BigDecimal j3 = j1.add(j2).divide(DOIS);
            BigDecimal q3 = financiamento(n, j3, p);
            BigDecimal m3 = q3.subtract(q0);
            if (m3.abs().compareTo(DELTA) <= 0) return j3;
            if (m3.signum() == m1.signum()) {
                q1 = q3;
                j1 = j3;
            } else {
                q2 = q3;
                j2 = j3;
            }
        }
        throw new ArithmeticException("Não convergiu"
                + ": q1=[" + q1 + "], j1=[" + j1 + "], m1=[" + m1 + "]"
                + ", q2=[" + q2 + "], j2=[" + j2 + "], m2=[" + m2 + "]");
    }

    private static void teste(int q0, int p, int n) {
        BigDecimal bdq0Ideal = new BigDecimal(q0);
        BigDecimal bdp = new BigDecimal(p);
        BigDecimal j = taxaFinanciamento(bdq0Ideal, n, bdp);
        BigDecimal bdq0Obtido = financiamento(n, j, bdp);
        System.out.println("----------");
        System.out.println("q0-ideal=[" + bdq0Ideal + "]");
        System.out.println("p=[" + bdp + "]");
        System.out.println("j=[" + j + "]");
        System.out.println("q0-obtido=[" + bdq0Obtido + "]");
        System.out.println("----------");
        System.out.println();
    }

    public static void main(String[] args) {
        teste(750, 86, 10);
        teste(750, 85, 10);
    }
}