Question

trying to get back into Java and have decided to tackle PI. So I made this program based on the Harmonic Series:

public static void main(String [] args)
{   
    double denominator = 1.0;
    double tempValue;
    double PI = 0.0;

    // End point for program
    double stopPoint = 1234.5;

    for( int i = 1; i < stopPoint; i++  )
    {
        tempValue = Math.sqrt( (1/(denominator*denominator))/6 );

        PI = PI + tempValue;
        denominator = denominator + 1.0;
    }
    System.out.println( "PI = " + PI );

The application prints this:

PI = 3.1417306496998294

So you can see its mildly working. But when I change the stopPoint value any more I'm not getting a change in precision, at all.

For example changing it to 1234.75 gives the same answer - or perhaps print can't display the exact value? If so what is the best way to print out values like these?

Thanks

EDIT

I've added this code as its a change to the code posted above. Some of the changes include the use of Big Decimal and the inclusion of a while loop instead of a for.

import java.math.BigDecimal;
import java.math.MathContext;

public class MyPI 
{
final static BigDecimal ONE = new BigDecimal(1);
final static BigDecimal SIX = new BigDecimal(6);

public static void main(String [] args)
{
    BigDecimal deno, temp, tempPI;

    int start, end;
    start = 1;
    end = 500000;
    temp = new BigDecimal(0);

    // Starting denominator point
    deno = ONE;

    while( start < end )
    {
        // Without precision and rounding mode, it will try to return a
        // never ending number
        temp = temp.add( ONE.divide(deno.pow(2),MathContext.DECIMAL64) );
        deno = deno.add(ONE);

        start = start + 1;
    }
    tempPI = temp.multiply(SIX);

    // Need to convert to double for square root
    double PI = Math.sqrt( tempPI.doubleValue() );
    System.out.println( "PI: " + PI );
}
}

This produces the following result:

PI: 3.1415907437318054

Thanks all for the help - will probably add a timer to track how long it takes to do this.

Was it helpful?

Solution

I've been using the BigDecimal type instead of the double, but I have hit a bit of a roadblock—the square root.

Don't take the square root of each term. As shown in this example, add the terms of the series, which has the exact sum π2/6. When your loop terminates, multiply by six and then take a single square root.

OTHER TIPS

If you want more precision, you can use Java's BigDecimal.

Use Java BigDecimal instead of Double that has a limited precision.

The BigDecimal class can give you "arbitrary-precision signed decimal numbers", which is what you want in this case, although the instances of BigDecimal are a little more tricky to work with than literals, the class actually works quickly and can be used to do what you need fairly accurately.

Just for your information, though, using the harmonic series to calculate Pi is pretty inefficient, but I understand doing it as a fun program or to learn something new.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top