Ghaida'
Ghaida'

Reputation: 11

using BigDecimal for very large numbers

I have this code:

while (counter <= t)
{
   a = a * counter;
   c = c * r + a;
   counter++;
}

and I have t with the value 101835.

The output should be 7.1*10^438, but NetBeans shows the output as infinity.

Is there anything that will make the output as a decimal number?

Upvotes: 0

Views: 2024

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477318

A double as defined by IEEE-754 can't represent such a number, it's too large. The bounds are approximately between -10308 and 10308.

You need to use a BigDecimal to represent it: a number with an arbitrary number of bytes to represent numbers.

Better way to implement this:

double c = 0.0005d;//initialize c
double r = 0.01d;  //initialize r
double a = 0.0006d;//initialize a
BigDecimal abd = new BigDecimal(a); //BigDecimal for a
BigDecimal cbd = new BigDecimal(c); //BigDecimal for c
BigDecimal rbd = new BigDecimal(r); //BigDecimal for r
for (int counter = 1; counter <= t; counter++) {//perhaps other offset for counter?
   abd = abd.multiply(new BigDecimal(counter));
   cbd = cbd.multiply(rbd).add(abd);
}

A potential problem with this approach is that the precision is too high: Java will calculate all operations exactly resulting in numbers that have thousands of digits. Since every operation blows up the number of digits, within a few iterations, simple addition and multiplication operations become unfeasible.

You can solve this by defining a precision using the optional MathContext parameter: it determines on how precise the result should be. You can for instance use MathContext.DECIMAL128:

int t = 101835;
double c = 0.0005d;//initialize c
double r = 0.01d;  //initialize r
double a = 0.0006d;//initialize a
BigDecimal abd = new BigDecimal(a); //BigDecimal for a
BigDecimal cbd = new BigDecimal(c); //BigDecimal for c
BigDecimal rbd = new BigDecimal(r); //BigDecimal for r
for (int counter = 1; counter <= t; counter++) {//perhaps other offset for counter?
    abd = abd.multiply(new BigDecimal(counter),MathContext.DECIMAL128);
    cbd = cbd.multiply(rbd,MathContext.DECIMAL128).add(abd,MathContext.DECIMAL128);
}
System.out.println(abd);
System.out.println(cbd);

This gives:

abd = 3.166049846031012773846494375835059E+465752
cbd = 3.166050156931013454758413539958330E+465752

This is approximately correct, after all the result of a should be:

enter image description here

Which is approximately correct according to Wolfram Alpha.

Furthermore I would advice to use a for and not a while if it is a for loop. Since while tends to create another type of infinity: an infinite loop ;).

Upvotes: 1

Am_I_Helpful
Am_I_Helpful

Reputation: 19168

Yes, the only thing which you should use here is BigDecimal class. It'll easily handle that complex value without burdening you.

The maximum supported double value is only around 1.7 * 10^ 308 as given by Double.MAX_VALUE specified for Java.

Upvotes: 1

Related Questions