Increase Precision with Bigdecimal Java

Asked

Viewed 790 times

4

Entrances

R = new BigDecimal(2.79E+00);
Dxm3d = new BigDecimal(3.99E-04);
Wmd = new BigDecimal(2.39E-03);
x = new BigDecimal(3.2);
t = new BigDecimal(365);

Below is the formula

BigDecimal segundoTermo = (R.multiply(x).subtract(Wmd.multiply(t)).divide(new BigDecimal(2d).multiply(new BigDecimal(Math.sqrt(Dxm3d.multiply(R).multiply(t).doubleValue()))), RoundingMode.HALF_DOWN));
System.out.println("valor do segundo termo pfv:" + segundoTermo);

Value returned

valor do segundo termo pfv:6.31838147917065306052600332590254032941338413886611227745342947009953030493273342105799365116070956364

Expected Value

6,321092458

These J263 values are the execel ballots that represent my variables.

  • J253 value: 2,39E-03 represents Wmd
  • J254 value: 3,99E-04 represents Dxm3d
  • J255 value: 2,79E+00 represents R
  • I259 value: 365 represents t
  • J263 value : 3,2 represents x

inserir a descrição da imagem aqui

inserir a descrição da imagem aqui

  • 1

    How did you find the expected value?

  • Ah. is why these formulas were made by a team of engineers here . which already has a progamma calling Mathcad that makes.

  • I have an excel here tbm and gives the expected value.

  • Are you sure the formula is calculating what you want it to calculate, no operators precedence errors?

  • @Math will edit to ask by placing the prints of the formulas and results past me.

  • @Math edited . with the fixed values of the parameters and the formula where I move to java. even so the result does not return the expected

  • 1

    Jose, could you please show all the values (R,x, Wmd, Dxm3d, etc)? Preferably just update your code with the /assignment statement of each variable so we can just copy and paste to check the example.

  • @Anthonyaccioly is pq these variables already depend on other previous values ai I would have to pass the complete class but I put the fixed values of each variables down there the question . can exchange the names of the variables for these values I have placed

Show 3 more comments

3 answers

2

My suspicion is that the input values are approximate and therefore causing the deviation in the final result.

For example, the value 2.79E+00 seems to have been printed in scientific notation with two decimal places because this was the standard of some software. In general, when a floating point number has only two decimal places, scientific notation is not adopted.

To illustrate what I’m saying, add a few more decimal places to the value of R and got a closer value. See the example:

BigDecimal R = new BigDecimal("2.791654").setScale(20);
BigDecimal x = new BigDecimal("3.2").setScale(20);
BigDecimal w = new BigDecimal("0.00239").setScale(20);
BigDecimal t = new BigDecimal("365").setScale(20);

//R.x - w.t
BigDecimal dividendo = R.multiply(x).subtract(w.multiply(t));

BigDecimal D = new BigDecimal("0.000399").setScale(20);
BigDecimal dois = new BigDecimal("2").setScale(20);

//2 . (D.R.t) ^ 1/2
BigDecimal divisor = new BigDecimal(Math.sqrt(D.multiply(R).multiply(t).doubleValue())).multiply(dois);

BigDecimal segundoTermo = dividendo.divide(divisor, RoundingMode.HALF_DOWN);
System.out.println("valor do segundo termo pfv:" + segundoTermo);

I made a few changes to make the example clearer, in addition to adding a larger number of decimals, but all this has little influence on the final result, other than the accuracy of the input numbers.

  • Thank you very much friend for the return. Indeed it worked. but there have been some changes in my previous results that were correct kk I’m analyzing. and Jajá give you a feedback. thanks again.

  • and for some reason when I run your code is giving it : Exception in thread "main" java.lang.Arithmeticexception: Rounding necessary

  • I discovered why pq values are String. why you use this approach ? Bigdecimal t = new Bigdecimal("365"). setScale(20);

  • Joseph. See my example in the comment of another answer (1000 character accuracy propagated for all operations, the starting values are Strings and there is no Double intermediate in my version). Me, utluiz and Douglas already point out that it is not a problem of scale, precision or rounding. Between the utluiz answer, the ideone and the Excel spreadsheet of my comments you have already had three examples that the input of your example are the problem. Trust us a little and review your entries, the problem is not the scale.

2

Very succinctly:

Mathcad (or other programs) use a different number of significant digits for both calculations and error function values. The values for the function used by Erf.java are here and use an implementation in accordance with this.

  • I understand but I have an Array of results that make these same formulas and the final hit result is correct. However, in the course of the loop, there are rounding that lose precision and say the result. The one you are sending is the index Dice 4 the previous ones work

  • @Josevieiraneto How much does Erf(1) in java?

  • I tested the error functions. separately and hit as same value of Mathcad or excel the problem is in fact in the formula or accuracy of the results.

  • I did exactly this test with the value 1 in java and tested tbm in Mathcad and excel . both give the same result

  • Why are you using Roundingmode.HALF_DOWN?

  • for some reason he is forcing me to have a Roudingmode. there are several. tested with both give the same result

  • Have you tried reducing the accuracy of Bigdecimal and rounding "normal"?

  • I’m with Alexandre that the input values are being adjusted. I changed his example to use an accuracy of 1000. I got rid of all the doubles, including the square root (see: http://stackoverflow.com/a/17306433/664577) and rounded upwards each time. The variation in the result was ~ 0.0005 - http://ideone.com/iajyM9. I highly doubt that rounding errors in this case would influence the second decimal place.

  • PS: To reinforce my theory that the entries are different, here is the result of the formula in Excel: http://1drv.ms/1U3ezNm. The result of the spreadsheet with the entries you passed is 6,318814578. This matches precisely with the first 9 houses of my version in Java.

Show 4 more comments

0

Having the value, a setScale with Round Half Up, should generate the result you want.

BigDecimal valor = 123;
BigDecimal resultado = new BigDecimal(String.valueOf(valor)).setScale(9, BigDecimal.ROUND_HALF_UP);
  • Did not work returned : 6.318381479

  • So it’s like @Alexandre said, the difference is somewhere else

  • @Josevieiraneto sees well the accuracy of all variables. The answer may be around.

  • So I put the fixed values I passed on the question gives a look I edited there msm so gives the same value

Browser other questions tagged

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