Saleh Feek
Saleh Feek

Reputation: 2076

Is there any wrong with this BigDecimal calculation?

I am new to BigDecimal.
I tried some math calculations using Java code. When I try the same calculations using Google calculator it gives me a slightly different results. Which one is the most accurate?. If Google calculator is more accurate, then how to improve java code to match it?.

On Google calculator:

134.23576185216913 - (134.23576185216913 × √(1 - (200000000^2 ÷ 299800000^2))) = 34.2357618522

On Java:

      BigDecimal t1 = new BigDecimal(134.23576185216913);
      BigDecimal one = new BigDecimal(1);
      BigDecimal speed = new BigDecimal(200000000).pow(2);
      BigDecimal lightsSpeed = new BigDecimal(299800000).pow(2);

      MathContext mc = new MathContext(2, RoundingMode.HALF_UP);
      System.out.println(t1.subtract((t1.multiply(SquareRoot.bigSqrt(one.subtract(speed.divide(lightsSpeed,mc)))))));

The method of bigSqrt is from here

The result is:

run: 34.683856455950090090043113321827989040137639817587194953722595479211000578082422197809603912048352550091209304856567024386365147605287692511973841869226169664820176852861655846233912503305984796190828666994508412096618025960010635831985100961879858807909056676663493607611105279976694118991120829708264297254294821755138400476425886154174804687500
BUILD SUCCESSFUL (total time: 0 seconds)

Upvotes: 4

Views: 481

Answers (2)

assylias
assylias

Reputation: 328598

This is your issue:

MathContext mc = new MathContext(2, RoundingMode.HALF_UP);

your are rounding the division to 2 decimal places. Use MathContext mc = new MathContext(15, RoundingMode.HALF_UP); instead (for example) and you should get something closer to the expected result.

You can see the difference with:

System.out.println(speed.divide(lightsSpeed,new MathContext(2, RoundingMode.HALF_UP)));
System.out.println(speed.divide(lightsSpeed,new MathContext(15, RoundingMode.HALF_UP)));

which prints:

0.45
0.445037630156818

Upvotes: 7

Codor
Codor

Reputation: 17605

It is a bit unclear to me what is happening mathematically and in terms of data structures. To my understanding, BigDecimal can represent only certain rational numbers, by no means arbitrary square roots. The linked method in SquareRoot would return some approximation of the actual square root, which also seems to be the case from a superficial inspection of the code.

Upvotes: 0

Related Questions