Comparison of Bigdecimal result with Float (Java)

Asked

Viewed 376 times

4

I have two formulas implemented, one with the Bigdecimal type and the other with the primitive double type, but the results differ and I am not able to find the solution. Below 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

Term values: (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 to the correct is the primitive double

  • What is the div?

  • There is another error: the expression with double has a factor of 1/2 and the Bigdecimal does not.

  • Alexandre a váriavel div é o que faz esse 1/2

  • @Math is the 1/2 you have in the other formula

  • 1

    Never use any of that, but I believe the error lies in the way you are incorrectly applying the add method. Try separating the test variable into two terms and adding them later to the part.

  • 1

    See also this: http://stackoverflow.com/questions/12944559/how-to-multiply-a-bigdecimal-by-an-integer-in-java

  • This question you pointed out I already use. :(

  • 1

    Are you sure? Because it looks like you’re testing=(1/2thermo_atermo_b) + 1/2) * termo_c * termo_4 and not what you want...

Show 3 more comments

1 answer

4


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

Simply put, your code is 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);
    }
}

Note that in the case of Double you make two multiplications and then sum with two more multiplications, in the case of Biginteger you multiply the terceiroTermo and the quartoTermo with the result of the first multiplications.

To fix it is 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 one ) just before the .add, that closes the new ( before the div.multiply, and also inserted a ( shortly after the .add, which is closed at the end of the sentence.

For my simplified example above, the result is:

Total value of Bxt in Bigdecimal: 43.0
BXT value: in Double 43.0

See it working on Ideone.

Leaving my simplification aside and putting the corrections in your code, replace the excerpt that calculates the result of teste by the following section:

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())))));
  • 1

    I’ll give you +1 tomorrow (I exceeded my number of votes for today). But I would like to comment that, for the sake of readability and to reduce the likelihood of error, it would have been better if the PA had separated the two terms. Then I wouldn’t have to go around in brackets.

  • 2

    Oh yes, a negative point of immutability is precisely this, it makes the code difficult to understand and requires that things be separated with more care to try to uncomplicate a little. PS: you vote for damn huh, rs.

  • Today I spent too much time on the forum...

  • @Josevieiraneto Ah, the first code is wrong, you have to replace the end section to work.

  • @Math still not rolling :(

  • @Math was I saw . my sorry mistake.

  • @Math but I did in the main I didn’t run came closer but n worked :(

  • @Math wants to take a look at my full class ?

  • @Josevieiraneto look at my updated reply, I changed the last paragraph.

  • @Math thank you so much now the two results so equal at least. now I don’t understand why the final value diverges from : 6,19E-20 is giving 6,41E-20

  • 1

    @Josevieiraneto Diverge little... To find out the reason for this you will need to see how the expected value was calculated.

  • @Alexandrecartaxo understand . I will create another question for you to understand better

  • @Alexandrecartaxo, http://answall.com/questions/105192/increment-precis%C3%A3o-com-bigdecimal-java

  • @Math, http://answall.com/questions/105192/increment-precis%C3%A3o-com-bigdecimal-java

  • +1 as promised.

Show 10 more comments

Browser other questions tagged

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