BigDecimal result comparison with Float (Java)

4

I have two formulas implemented, one with the BigDecimal type and the other with the double primitive type, but the results diverge and I can not find the solution. Here are the formulas:

BigDecimal x = new BigDecimal(3.2d); //TODO: entradas do usuário
BigDecimal t = new BigDecimal(365d);
/**
 * Convertendo valor de v para m/d
 */
//double Vmd = v * Math.pow(10d, -2d);
BigDecimal Vmd = new BigDecimal(v * Math.pow(10d, -2d));
/**
 * convertendo valor de W para m/d
 */
//double Wmd = W / 100d;
BigDecimal Wmd = new BigDecimal(W / 100d);
BigDecimal div = new BigDecimal(1d/2d);
BigDecimal teste = div.multiply(new BigDecimal(Math.exp(primeiroTermo.doubleValue()))).
                     multiply(new BigDecimal( Erf.erfc(seguntoTermo.doubleValue())).add(div)
                    .multiply(new BigDecimal(Math.exp(terceiroTermo.doubleValue())))
                    .multiply(new BigDecimal(Erf.erfc(quartoTermo.doubleValue()))));

System.out.println("Valor total de Bxt em BigDecimal: " + nb.format(teste));

Bxt = (1d/2d) * (Math.exp(primeiroTermo.doubleValue())) * Erf.erfc(seguntoTermo.doubleValue()) + (1d/2d) * (Math.exp(terceiroTermo.doubleValue())) * Erf.erfc(quartoTermo.doubleValue());

System.out.println("Valor de BXT: em Double " + nb.format(Bxt));

Final Value:

Valor total de Bxt em BigDecimal: 1,63E6
Valor de BXT: em Double 6,41E-20
Valor esperado : 6,19E-20

Values of the terms: (input values for formulas)

valor do primeiro termo : -1,75E0
valor do segundo termo :6.31838147917065306052600332590254032941338413886611227745342947009953030493273342105799365116070956364
valor do terceiro termo :1,74E1
valor do quartoTermo termo :7.68858730163961471709076409364321640056053538848914223720418242638997018233141713029583833874949308593

The closest result of correct is double primitive

    
asked by anonymous 22.12.2015 / 17:48

1 answer

4

The problem in this case is that you have changed the precedence of the operators, and consequently you are getting another value.

Simply put, your code looks like this:

public class Teste {
    public static void main(String[] args) {
        Integer primeiroTermo = 5;
        Integer segundoTermo = 6;
        Integer terceiroTermo = 7;
        Integer quartoTermo = 8;

        BigDecimal div = new BigDecimal(1d/2d);
        BigDecimal teste = div.multiply(new BigDecimal(primeiroTermo.doubleValue()))
                            .multiply(new BigDecimal(segundoTermo.doubleValue()).add(div)
                            .multiply(new BigDecimal(terceiroTermo.doubleValue()))
                            .multiply(new BigDecimal(quartoTermo.doubleValue())));

        System.out.println("Valor total de Bxt em BigDecimal: " + teste);

        Double Bxt =
                (1d/2d) * primeiroTermo.doubleValue() * segundoTermo.doubleValue() + 
                (1d/2d) * terceiroTermo.doubleValue() * quartoTermo.doubleValue();

        System.out.println("Valor de BXT: em Double " + Bxt);
    }
}

Notice that for Double's case you make two multiplications and then add two more multiplications, in BigInteger's case you multiply the terceiroTermo and the quartoTermo with the result of the first multiplications.

To fix it looks like this:

BigDecimal teste = (div.multiply(new BigDecimal(primeiroTermo.doubleValue()))
                    .multiply(new BigDecimal(segundoTermo.doubleValue())).add((div)
                    .multiply(new BigDecimal(terceiroTermo.doubleValue()))
                    .multiply(new BigDecimal(quartoTermo.doubleValue()))));

Notice that I inserted a ) earlier than .add , which closes the new ( before the div.multiply , and also inserted a ( soon after the .add , which is closed at the end of the sentence.

For my simplified example above, the result is:

  

Total Bxt value in BigDecimal: 43.0
  BXT Value: in Double 43.0

See working on Ideone .

Leaving my simplification aside and putting the fixes in your code, replace the snippet that calculates the result of teste with the following snippet:

BigDecimal teste = (div.multiply(new BigDecimal(Math.exp(primeiroTermo.doubleValue()))).
        multiply(new BigDecimal( Erf.erfc(seguntoTermo.doubleValue()))).add((div)
       .multiply(new BigDecimal(Math.exp(terceiroTermo.doubleValue())))
       .multiply(new BigDecimal(Erf.erfc(quartoTermo.doubleValue())))));
    
22.12.2015 / 19:04