6
\$\begingroup\$

I need to calculate pi to 7 significant figures in Java—without using Math.PI.

Here is the code I came up with to do that:

public class ComputePI 
{   
    public static void main(String[] args) 
    {       
        double sum = 0.0;
        double sumOne = 0.0;
        double delta;
        int counter = 0;
        final double DENOMINATOR_CANCEL = 4.0;
        final int LARGE_NUMBER = 5000000;
        final double SMALLEST_DELTA = 0.0000004535899;
        boolean closeEnough = false;      

        for (int j = 1; j < LARGE_NUMBER; j += 2) // Computes number close to pi
        {
            double firstFrac = (1.0 / (j * 2.0 - 1.0));
            double secondFrac = (1.0 / (j * 2.0 + 1.0));
            sumOne += firstFrac - secondFrac;
        }

        for (int i = 1; (!closeEnough); i += 2)   //"My computed value of pi" 
        {
            double firstNum = (1.0 / (i * 2.0 - 1.0));
            double secondNum = (1.0 / (i * 2.0 + 1.0));     
            sum += firstNum - secondNum;
            delta = sumOne * DENOMINATOR_CANCEL - sum * DENOMINATOR_CANCEL;
            if (delta < SMALLEST_DELTA)     // If delta reaches 7-sig accuracy
            {
                closeEnough = true;         // End loop
            }
            counter = i / 2;        // Counts iterations
        }

                        /*  output results      */
        System.out.println("My computed value of pi is: " + sum * DENOMINATOR_CANCEL);
        System.out.println("The library constant value of pi is: " + Math.PI);
        System.out.println("The number of iterations needed to reach " + "seven-significant digit accuracy is: " + counter);
    }       
}

Is this a good approach, or is it horribly inefficient? How might I improve it?

Perhaps having a for loop inside a for loop would work better. One with n+1 iterations, the other with n iterations. The loop would terminate if the two sums were subtracted, and produced a difference of 0.0000009 or less (7 significant figure accuracy).

\$\endgroup\$

migrated from stackoverflow.com Sep 6 '17 at 21:30

This question came from our site for professional and enthusiast programmers.

3
\$\begingroup\$

Your implementation is fine. You could add some tweaks (i += 4 instead of i += 2) to avoid multiplying i by 2.0, but this won't help much to make your program fast.

This is because you chose a simple formula, but that formula converges very slowly towards \$\pi\$.

Read on Wikipedia about efficient algorithms for computing \$\pi\$, there are several.

Or, if you want to cheat a bit, just return 4 * Math.atan(1.0).

You don't need a delta in the whole program, so only declare it where you really need it. You already did that with firstFrac, for example.

Be consistent with your chosen names. What's the difference between firstFrac and firstNum? — There is none, therefore you should use the same name in both places.

What does sumOne mean? Think of a better name for it.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.