0

I am writing a program in which I have to repeatedly multiply two BigDecimal.

After the 27th iteration, I get:

0.905225895893387921845435055445776361046057346344145563957027726

Any further calculations using this number (BigDecimal * 0.182365681285) results in trailing zeros. So the next iteration returns: 0.905225895893387921845435055445776361046057346344145563957027726000000000000

The iteration after that returns: 0.905225895893387921845435055445776361046057346344145563957027726000000000000000000000000

etc..


So I was wondering if this was due to some precision issue with BigDecimal.

Any help is appreciated

Edit: I was asked to post my code. I could copy paste the few pages I have, but this is a very accurate representation of what I have so far:

BigDecimal range = new BigDecimal(0.0012440624293146346);
for(int i = 0; i < 50 ; i++){
    low = low.multiply(range);
}

2 Answers2

1

The multiply method creates a BigDecimal which has a scale equal to the scale of the first operand + the scale of the second operand, even if that leads to trailing zeros. To strip the trailing zeros, use... stripTrailingZeros().

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • I tried stripping the trailing zeros, but that's not the result I'm trying to achieve, I just get the same number between the 27th and 50th iteration, which makes no sense. – John McBrown Mar 16 '13 at 23:35
  • 1
    @JohnMcBrown You are right, it doesn't. Can you provide the code which reproduces this issue? – Peter Lawrey Mar 16 '13 at 23:36
  • I must apologize, but I would have to link hundreds of files. I do appreciate all the advice I've gotten so far, and I'll be sure to uprate them. It's good to know I'm not dealing with a problem with BigDecimal – John McBrown Mar 16 '13 at 23:40
  • @JohnMcBrown The implication of this answer is that if you want more precision you must increase the precision of the operands. The original operand doesn't even have the precision it appears to have, because that literal is already truncated by the compiler. Provide it as a String, not a numerical literal, and if necessary adjust the precision of the BigDecimal as well. – user207421 Mar 17 '13 at 00:11
0

I have found a situation while simulates trailing zeros.

BigDecimal bd = BigDecimal.valueOf(0.5);
BigDecimal a = BigDecimal.valueOf(1 << 20).divide(BigDecimal.valueOf(1000000));
for (int i = 0; i < 20; i++) {
    System.out.println(a);
    a = a.multiply(bd);
}

Note: BigDecimal doesn't assume you want to strip trailing zeros by default

1.048576
0.5242880
0.26214400
0.131072000
0.0655360000
0.03276800000
0.016384000000
0.0081920000000
0.00409600000000
0.002048000000000
0.0010240000000000
0.00051200000000000
0.000256000000000000
0.0001280000000000000
0.00006400000000000000
0.000032000000000000000
0.0000160000000000000000
0.00000800000000000000000
0.000004000000000000000000
0.0000020000000000000000000

There is no reason you should be getting zero's which shouldn't be there unless you are multiplying double values converted to BigDecimal each time.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • In the situation you described, I can strip the trailing zeros and have an accurate number. In my situation, I get the exact same number every iteration after the 27th. Stripping the trailing zeros just results in the exact same number. I can't understand why – John McBrown Mar 16 '13 at 23:38
  • 1
    You need to log the values you multiplied and the result you get. This way you should be able to reproduce the calculation with one line. Which version of Java are you using? If you have an old version of Java 5.0 it could be a bug. – Peter Lawrey Mar 16 '13 at 23:42