I am trying to write a program that calculates the value of pi from the infinite series of pi = 4 - 4/3 + 4/5 - 4/7 + 4/9...etc.
As you can tell, the numerator stays at 4, while the denominator goes up incrementally in odd numbers, if the program finds pi, or a form of it, hopefully that will be displayed. The problem is that only the first value is calculated, i am experimenting with a for loop, but it is infinite, and I am lost upon how to proceed.

package pi;

public class pi1 {

    public static void main(String[] args) {
        double plusminus = 0;
        double top = 4;
        double bot = 1;
        double pi = 4;
        double newbot = bot + 2;
        double piequals = top/newbot;
        while(plusminus == 0 || plusminus == 1){
        //if (plusminus == 0 || plusminus == 1){
            //for (int count = 1; count <=5; count++)
                if (plusminus == 0){
                    pi = pi + piequals;
                    plusminus = plusminus + 1;
                    if (pi == 3.14){
                        System.out.println("π = 3.14?");
                    }
                    if (pi == 3.141){
                        System.out.println("π = 3.141?");
                    }
                    if (pi == 3.1415){
                        System.out.println("π = 3.1415?");
                    }
                    if (pi == 3.14159){
                        System.out.println("π = 3.14159?");
                    }
                    else {
                        System.out.println("π = " + pi);
                    }
                if (plusminus == 1){
                    pi = pi - piequals;
                    plusminus = plusminus - 1;
                    if (pi == 3.14){
                        System.out.println("π = 3.14?");
                    }
                    if (pi == 3.141){
                        System.out.println("π = 3.141?");
                    }
                    if (pi == 3.1415){
                        System.out.println("π = 3.1415?");
                    }
                    if (pi == 3.14159){
                        System.out.println("π = 3.14159?");
                    }
                    else {
                        System.out.println("π = " + pi);
                    }

            }
            }
        }        
    }
}

Recommended Answers

All 31 Replies

you have infinite loop because you are checking for plusminus == 0 or 1. when the value is 0, you add 1, when the value is 1 you subtract 1, therefore the condition is always satisfied.

your for loop is commented out, you are actually using a while loop.

Yes, I understand that, I wrote that, I was trying out the for loop to see if it was outputting a different result, do you have any suggestions to make the condition add or subtract the value while being infinite?

ok, i am not entirely sure what approach you taking for this problem, but it seems a bit iffy so far. do you actually want an infinite loop? (i would have though not...)

anyway, the maths needs to be calculated for each iteration of the loop, however you decide to define it. you need to be re-calculating piequals each time, and using the new value for your addition / subtraction.

i was initially confused by your 2 conditions but now i realise this is your odd/even separation (there are probably better ways to do this, but it'll work, lol).

why do you have all the conditional statements for pi?

anyway hope that gives you a start.

I want the program to be infinite, but when it finds the last pi, 3.14159, it will stop and display how many terms of the series it went thought before getting to it, i havn't yet added that to the program.

I was hoping to accomplish the recalculation of piequals, by the lines

pi = pi + piequals;

and

pi = pi - piequals;

...but that did not work, how might I go about calculating the math for each iteration of the loop? Here is what I have, the for loop cannot be infinite.

public static void main(String[] args) {
        int count = 0;
        double plusminus = 0;
        double top = 4;
        double bot = 1;
        double pi = 4;
        double newbot = bot + 2;
        double piequals = top/newbot;
        while(plusminus == 0 || plusminus == 1){
                if (plusminus == 0){
                    pi = pi + piequals;
                    plusminus = plusminus + 1;
                    count++;
                    if (pi == 3.14){
                        System.out.println("π = 3.14?");
                    }
                    if (pi == 3.141){
                        System.out.println("π = 3.141?");
                    }
                    if (pi == 3.1415){
                        System.out.println("π = 3.1415?");
                    }
                    if (pi == 3.14159){
                        System.out.println("π = 3.14159?");
                        break;
                    }
                    else {
                        System.out.println("π = " + pi);
                    }
                if (plusminus == 1){
                    pi = pi - piequals;
                    plusminus = plusminus - 1;
                    count++;
                    if (pi == 3.14){
                        System.out.println("π = 3.14?");
                    }
                    if (pi == 3.141){
                        System.out.println("π = 3.141?");
                    }
                    if (pi == 3.1415){
                        System.out.println("π = 3.1415?");
                    }
                    if (pi == 3.14159){
                        System.out.println("π = 3.14159?");
                        break;
                    }
                    else {
                        System.out.println("π = " + pi);
                    }

            }
            }
        }        
    }
}

that is recalculating "pi" not "piequals". look at the mathematical sequence, you should see what is happening...

...how is the program supposed to keep recalculating piequals if it is running the same thing over and over? how do I differentiate this with a while loop?

public static void main(String[] args) {
        int count = 0;
        double plusminus = 0;
        double top = 4;
        double bot = 1;
        double pi = 4;
        double piequals = top/bot;
        while(plusminus == 0 || plusminus == 1){
                if (plusminus == 0){
                    piequals = top/(bot+2);
                    pi = pi + piequals;
                    plusminus = plusminus + 1;
                    count++;
                    if (pi == 3.14){
                        System.out.println("π = 3.14?");
                        System.out.printf("This took " + count + "times\n");
                    }
                    if (pi == 3.141){
                        System.out.println("π = 3.141?");
                        System.out.printf("This took " + count + "times\n");
                    }
                    if (pi == 3.1415){
                        System.out.println("π = 3.1415?");
                        System.out.printf("This took " + count + "times\n");
                    }
                    if (pi == 3.14159){
                        System.out.println("π = 3.14159?");
                        System.out.printf("This took " + count + "times\n");
                        break;
                    }
                    else {
                        System.out.println("π = " + pi);
                    }
                if (plusminus == 1){
                    piequals = top/(bot+2);
                    pi = pi - piequals;
                    plusminus = plusminus - 1;
                    count++;
                    if (pi == 3.14){
                        System.out.println("π = 3.14?");
                        System.out.printf("This took " + count + "times\n");
                    }
                    if (pi == 3.141){
                        System.out.println("π = 3.141?");
                        System.out.printf("This took " + count + "times\n");
                    }
                    if (pi == 3.1415){
                        System.out.println("π = 3.1415?");
                        System.out.printf("This took " + count + "times\n");
                    }
                    if (pi == 3.14159){
                        System.out.println("π = 3.14159?");
                        System.out.printf("This took " + count + "times\n");
                        break;
                    }
                    else {
                        System.out.println("π = " + pi);
                    }

            }
            }
        }        
    }
}

you have already answered your question yourself. you are using a "counter" and so using this you can emulate the sequence.

using count i would emulate going through the loop and adding/subtracting the needed values? I am completely blocking on any way to do this

Do not compare a double to a double using the equality operator. It's extremely unlikely that the two numbers will be exactly the same. Instead, set up a tolerance and quit once you get there.

double piestimate = 0.0;
double TOLERANCE = 0.0001;
double piroundoff = 3.14159;

while (Math.abs (piroundoff - piestimate) > TOLERANCE)
{
    double term = /* calculate next term */
    piestimate = piestimate + term;
}

// piestimate now holds an estimate of pi

A more common way of doing it is to NOT supply your own estimates and have the loop continue until the value of term is less than TOLERANCE:

double term = 4.0; // first term
double piestimate = term;
double TOLERANCE = 0.0001;

while (Math.abs (term) > TOLERANCE)
{
    term = /* calculate next term */
    piestimate = piestimate + term;
}

// piestimate now holds an estimate of pi
public static void main(String[] args) {
        int count = 1;
        double plusminus = 0;
        double top = 4;
        double bot = 1;
        double pi = 4;
        double piequals = top/bot;
        
        while(plusminus == 0 || plusminus == 1){
        	if (plusminus == 0){
                    piequals = top /(bot+(count*2));
                    pi = pi - piequals;
                    plusminus = plusminus + 1;
                    if (pi == 3.14){
                        System.out.println("p = 3.14?");
                        System.out.printf("This took " + count + "times\n");
                    }
                    if (pi == 3.141){
                        System.out.println("p = 3.141?");
                        System.out.printf("This took " + count + "times\n");
                    }
                    if (pi == 3.1415){
                        System.out.println("p = 3.1415?");
                        System.out.printf("This took " + count + "times\n");
                    }
                    if (pi == 3.14159){
                        System.out.println("p = 3.14159?");
                        System.out.printf("This took " + count + "times\n");
                        break;
                    }
                    else {
                        System.out.println("p = " + pi);
                    }
                }
        	else if (plusminus == 1){
                    piequals = top/(bot+(count*2));
                    pi = pi + piequals;
                    plusminus = plusminus - 1;
                    
                    if (pi == 3.14){
                        System.out.println("p = 3.14?");
                        System.out.printf("This took " + count + "times\n");
                    }
                    if (pi == 3.141){
                        System.out.println("p = 3.141?");
                        System.out.printf("This took " + count + "times\n");
                    }
                    if (pi == 3.1415){
                        System.out.println("p = 3.1415?");
                        System.out.printf("This took " + count + "times\n");
                    }
                    if (pi == 3.14159){
                        System.out.println("p = 3.14159?");
                        System.out.printf("This took " + count + "times\n");
                        break;
                    }
                    else {
                        System.out.println("p = " + pi);
                    }
                }
                count++;
        }        
    }

im not looking for that exact value, im looking for it in the numbers that occur, such as if 3.140593058 comes up, it will find 3.14, is there a way to do that, that is a little simpler?

im not looking for that exact value, im looking for it in the numbers that occur, such as if 3.140593058 comes up, it will find 3.14, is there a way to do that, that is a little simpler?

if (pi == 3.14){
                        System.out.println("π = 3.14?");
                        System.out.printf("This took " + count + "times\n");
                    }
                    if (pi == 3.141){
                        System.out.println("π = 3.141?");
                        System.out.printf("This took " + count + "times\n");
                    }
                    if (pi == 3.1415){
                        System.out.println("π = 3.1415?");
                        System.out.printf("This took " + count + "times\n");
                    }
                    if (pi == 3.14159){
                        System.out.println("π = 3.14159?");
                        System.out.printf("This took " + count + "times\n");
                        break;
                    }

My point is that the if statements on lines 1, 5, 9, or 13 are extremely unlikely to ever be true. You rarely, if ever, compare a double to a double using the == operator. That's why I recommended using a tolerance to see if you are close.

im not looking for that exact value, im looking for it in the numbers that occur, such as if 3.140593058 comes up, it will find 3.14, is there a way to do that, that is a little simpler?

What does "it" refer to and what are you trying to "find"? You can compare 3.140593058 and 3.14 to compare if they are "close" (within a tolerance). Is that "finding" 3.14? 3.14 is an estimate itself, so you have two estimates? Are you checking whether the two estimates are close to each other?

i want to check how many digits of pi are correct from the output
as in, if 3.1403483 comes out, it will see that 3.14 is correct, but if 3.14150240249, it will see that 3.1415 is correct.
would it be simpler to do it to decimal places such as if (pi %.2 == 3.14) ?
but that does not seem to work...

if you are using == you are going to need to trim the decimal places down regardless. just make sure you do comparisons in an order that ensure you get what you want.

e.g. 3.1415024
2 decimals = 3.14
4 decimals = 3.1415

do you see how issues could arise with the code you currently have?

i want to check how many digits of pi are correct from the output
as in, if 3.1403483 comes out, it will see that 3.14 is correct, but if 3.14150240249, it will see that 3.1415 is correct.
would it be simpler to do it to decimal places such as if (pi %.2 == 3.14) ?
but that does not seem to work...

You can multiply both numbers and take the floor, so to check for two decimal places, multiply by 10^2 or 100 and take the floor:

if ((int)Math.floor (piestimate * 100) == 314)
{
    System.out.println ("Matched to at least two decimal places.");
}

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html#floor(double)

To check for three decimal places:

if ((int) Math.floor (piestimate * 1000) == 3141)
{
    System.out.println ("Matched to at least three decimal places.");
}

Edit : Make sure you cast the number to an integer!

maybe a continuous if statement

if (pi %.5 != 3.14159)
                    if (pi %.4 != 3.1415)
                        if (pi %.3 != 3.141)
                            if (pi %.2 == 3.14)

I now completely understand it, but....if the program finds 3.14, and then finds it again it still prints it, I want it to find 3.14, then only look for 3.141, then 3.1415, etc. As in only printing how many times it took to get 3.14 (or other numbers) the first time. I just learned about

continue;

would that be good to use, or just skip it, and leave the break until the end?

like i said, you were going to run into this issue. look for the longer numbers first since they are harder to satisfy. make sure you use if / else if so that multiple conditions aren't met in the same the loop. alternatively, yes "continue" could be something you would like to use, but not necessary here. if you only want to display each comparison once you are going to need to keep tract of which have already been found.

I now completely understand it, but....if the program finds 3.14, and then finds it again it still prints it, I want it to find 3.14, then only look for 3.141, then 3.1415, etc. As in only printing how many times it took to get 3.14 (or other numbers) the first time. I just learned about

continue;

would that be good to use, or just skip it, and leave the break until the end?

How about a boolean flag?

boolean foundTwoDigitPrecision = false;

/* code */
while (/* condition */)
{
    /* code */
    if (!foundTwoDigitPrecision && (int)Math.floor (piestimate * 100) == 314)
    {
        foundTwoDigitPrecision = true;
        System.out.println ("Matched to at least two decimal places.");
    }
    /* code */
}

how about something like this, the boolean is set to false, but if it the 3.14 loop goes through, it sets the boolean to true, making it not run again, any suggestions to make this work?

public static void main(String[] args) {
        int count = 1;
        double plusminus = 0;
        double top = 4;
        double bot = 1;
        double pi = 4;
        double piequals = top/bot;
        boolean x = false;
        boolean twofound = false;
        boolean threefound = false;
        boolean fourfound = false;
        boolean fivefound = false;

        while(plusminus == 0 || plusminus == 1){
        	if (plusminus == 0){
                piequals = top /(bot+(count*2));
                pi = pi - piequals;
                plusminus = plusminus + 1;
                if ((int)Math.floor (pi * 100) == 314) {
                    System.out.println("\nπ = 3.14?");
                    System.out.printf("This took " + count + "times\n");
                    System.out.println("-------------------------------");
                    twofound = true;
                }
                if ((int) Math.floor (pi * 1000) == 3141) {
                    System.out.println("\nπ = 3.141?");
                    System.out.printf("This took " + count + "times\n");
                    System.out.println("-------------------------------");
                    threefound = true;
                }
                if ((int) Math.floor (pi * 10000) == 31415){
                    System.out.println("\nπ = 3.1415?");
                    System.out.printf("This took " + count + "times\n");
                    System.out.println("-------------------------------");
                    fourfound = true;
                }
                if ((int) Math.floor (pi * 100000) == 314159){
                    System.out.println("\nπ = 3.14159?");
                    System.out.printf("This took " + count + "times\n");
                    System.out.println("-------------------------------");
                    fivefound = true;
                    break;
                }
//                else {
//                    System.out.println("π = " + pi);
//                }
            }
        else if (plusminus == 1){
                piequals = top/(bot+(count*2));
                pi = pi + piequals;
                plusminus = plusminus - 1;
                if (twofound = false){
                if ((int)Math.floor (pi * 100) == 314) {
                    System.out.println("\nπ = 3.14?");
                    System.out.printf("This took " + count + "times\n");
                    System.out.println("-------------------------------");
                    twofound = true;
                }
                }
                if (threefound = false){
                if ((int) Math.floor (pi * 1000) == 3141) {
                    System.out.println("\nπ = 3.141?");
                    System.out.printf("This took " + count + "times\n");
                    System.out.println("-------------------------------");
                    threefound = true;
                }
                }
                if (fourfound = false){
                if ((int) Math.floor (pi * 10000) == 31415){
                    System.out.println("\nπ = 3.1415?");
                    System.out.printf("This took " + count + "times\n");
                    System.out.println("-------------------------------");
                    fourfound = true;
                }
                }
                if (fivefound = false){
                if ((int) Math.floor (pi * 100000) == 314159){
                    System.out.println("\nπ = 3.14159?");
                    System.out.printf("This took " + count + "times\n");
                    System.out.println("-------------------------------");
                    fivefound = true;
                    break;
                }
                }
//                else {
//                    System.out.println("π = " + pi);
//                }
        }
                count++;
        }
    }
}

edit @ vernondozier, i just realized you suggested a similar thing, great minds think alike!

add conditions to if plusminus == 0 block and it should work...

now the program wont display anything?

public static void main(String[] args) {
        int count = 1;
        double plusminus = 0;
        double top = 4;
        double bot = 1;
        double pi = 4;
        double piequals = top/bot;
        boolean twofound = false;
        boolean threefound = false;
        boolean fourfound = false;
        boolean fivefound = false;

        while(plusminus == 0 || plusminus == 1){
        	if (plusminus == 0){
                piequals = top /(bot+(count*2));
                pi = pi - piequals;
                plusminus = plusminus + 1;
                if (twofound = false){
                    if ((int)Math.floor (pi * 100) == 314) {
                        System.out.println("\nπ = 3.14?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        twofound = true;
                    }
                }
                if (threefound = false){
                    if ((int) Math.floor (pi * 1000) == 3141) {
                        System.out.println("\nπ = 3.141?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        threefound = true;
                    }
                }
                if (fourfound = false){
                    if ((int) Math.floor (pi * 10000) == 31415){
                        System.out.println("\nπ = 3.1415?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        fourfound = true;
                    }
                }
                if (fivefound = false){
                    if ((int) Math.floor (pi * 100000) == 314159){
                        System.out.println("\nπ = 3.14159?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        fivefound = true;
                        break;
                    }
                }
//                else {
//                    System.out.println("π = " + pi);
//                }
            }
        else if (plusminus == 1){
                piequals = top/(bot+(count*2));
                pi = pi + piequals;
                plusminus = plusminus - 1;
                if (twofound = false){
                    if ((int)Math.floor (pi * 100) == 314) {
                        System.out.println("\nπ = 3.14?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        twofound = true;
                    }
                }
                if (threefound = false){
                    if ((int) Math.floor (pi * 1000) == 3141) {
                        System.out.println("\nπ = 3.141?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        threefound = true;
                    }
                }
                if (fourfound = false){
                    if ((int) Math.floor (pi * 10000) == 31415){
                        System.out.println("\nπ = 3.1415?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        fourfound = true;
                    }
                }
                if (fivefound = false){
                    if ((int) Math.floor (pi * 100000) == 314159){
                        System.out.println("\nπ = 3.14159?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        fivefound = true;
                        break;
                    }
                }
//                else {
//                    System.out.println("π = " + pi);
//                }
        }
                count++;
        }
    }
}

ive been trying to iterate over the value breaker and change the value if the greatest value of 3.14159 has been found. the program is not displaying anything?

public static void main(String[] args) {
        int breaker = 0;
        int count = 1;
        double plusminus = 0;
        double top = 4;
        double bot = 1;
        double pi = 4;
        double piequals = top/bot;
        while(plusminus == 0 || plusminus == 1){
        	if (plusminus == 0){
                piequals = top /(bot+(count*2));
                pi = pi - piequals;
                plusminus = plusminus + 1;
                //if (twofound = false){
                if (breaker == 0){
                    if ((int)Math.floor (pi * 100) == 314) {
                        System.out.println("\nπ = 3.14?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        //twofound = true;
                    }
                //if (threefound = false){
                    if ((int) Math.floor (pi * 1000) == 3141) {
                        System.out.println("\nπ = 3.141?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        //threefound = true;
                    }
                
                //if (fourfound = false){
                    if ((int) Math.floor (pi * 10000) == 31415){
                        System.out.println("\nπ = 3.1415?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        //fourfound = true;
                    }
                //}
                //if (fivefound = false){
                    if ((int) Math.floor (pi * 100000) == 314159){
                        System.out.println("\nπ = 3.14159?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        //fivefound = true;
                        breaker = 1;
                    }
                
                //}
//                else {
//                    System.out.println("Ï€ = " + pi);
//                }
            //}
        else if (plusminus == 1){
                piequals = top/(bot+(count*2));
                pi = pi + piequals;
                plusminus = plusminus - 1;
                //if (twofound = false){
                    if ((int)Math.floor (pi * 100) == 314) {
                        System.out.println("\nπ = 3.14?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        //twofound = true;
                    }
                //}
                //if (threefound = false){
                    if ((int) Math.floor (pi * 1000) == 3141) {
                        System.out.println("\nπ = 3.141?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        //threefound = true;
                    }
                //}
                //if (fourfound = false){
                    if ((int) Math.floor (pi * 10000) == 31415){
                        System.out.println("\nπ = 3.1415?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        //fourfound = true;
                    }
                //}
                //if (fivefound = false){
                    if ((int) Math.floor (pi * 100000) == 314159){
                        System.out.println("\nπ = 3.14159?");
                        System.out.printf("This took " + count + "times\n");
                        System.out.println("-------------------------------");
                        breaker = 1;
                    }
        }
                //}
//                else {
//                    System.out.println("Ï€ = " + pi);
//                }
        }
                else{
                    break;
                }
                count++;
        }
    //}
}
    }
}

Be careful when you comment things out. Look at lines 39 through 52. There is a bracket on line 45 that goes with the if statement on line 39, then you have an else if on line 52 and you've commented everything out in between, so that else if statement on line 52 goes with the if statement on line 39. Is that what you want? You need to be extremely careful, when commenting out if blocks, not to comment out one bracket too many or one bracket too few because that screws up the entire structure. If you had to stick an extra bracket somewhere after commenting to get it to compile, that's a good hint that you accidentally commented out something you didn't want to or didn't comment out something you wanted to.

Just as a matter of curiosity, I tried putting together a neat/compact version of this for my own amusement, and was surprised to see a strange pattern in the number of iterations needed for different number of decimal places correct.

Iteration 19  3.09162380666784, correct to ±0.05 (1 decimal place)
Iteration 199  3.136592684838816, correct to ±0.0050 (2 decimal places)
Iteration 1999  3.1410926536210413, correct to ±5.0E-4 (3 decimal places)
Iteration 19999  3.1415426535898248, correct to ±5.0E-5 (4 decimal places)
Iteration 200000  3.141597653564762, correct to ±5.0E-6 (5 decimal places)

Has anyone else tried this and found the same thing, or do I just have some stupid bug in my code?

Just as a matter of curiosity, I tried putting together a neat/compact version of this for my own amusement, and was surprised to see a strange pattern in the number of iterations needed for different number of decimal places correct.

Iteration 19  3.09162380666784, correct to ±0.05 (1 decimal place)
Iteration 199  3.136592684838816, correct to ±0.0050 (2 decimal places)
Iteration 1999  3.1410926536210413, correct to ±5.0E-4 (3 decimal places)
Iteration 19999  3.1415426535898248, correct to ±5.0E-5 (4 decimal places)
Iteration 200000  3.141597653564762, correct to ±5.0E-6 (5 decimal places)

Has anyone else tried this and found the same thing, or do I just have some stupid bug in my code?

I'd have to see the code, but it doesn't seem strange to me that the number of iterations it takes to reach a particular tolerance would take the pattern you describe. Consider iteration 200,000. The 200,000 term is roughly 4 / (200,000 * 2) = 1 / 100,000 = 0.00001, which is 5 decimal places. The terms jump back and forth over the real value of PI, alternately being greater and less than PI, so PI is approximately halfway in between each pair of successive approximations, so cut that 0.00001 in half and you are approximately 0.000005 from PI at the 200,000th iteration, which is exactly what your program found. Aside from a few round-off errors, it should always take 10 times as many iterations to get to the next level of precision, so I'd say your program is working correctly and there is no bug (I'm assuming your program is comparing the estimate to the ACTUAL value of PI and not the truncated value as the OP's program does. I would not be surprised if the OP's program doesn't exhibit the nice pattern that yours does).

I'd have to see the code, but it doesn't seem strange to me...

Thanks Vernon, that's reassuring! Still seems a bit of a coincidence that the numbers are quite so "memorable". I'll post the code after this, and maybe, if you have a minute, you could cast your eye over it for stupidities? It's barely more than a dozen statements, nothing too tedious. Thanks
James.

double estimatePi(int decimalPlacesRequired, int maxIterations) {
  // pi = 4 - 4/3 + 4/5 - 4/7 + 4/9...etc.

  double tolerance = .05;    // ±.05 = correct to 1 decimal place
  int decimalPlacesOK = 0; // current level of success

  double p = 4; // current estimate for Pi
  int sign = 1; // alternating sign of terms in series
  for (int i = 1; i < maxIterations; i++) {
    p += (sign = -sign) * 4.0 / (i * 2 + 1);

    if (Math.abs(Math.PI - p) < tolerance) {
        // now accurate within tolerance
        decimalPlacesOK++;
        System.out.println("Iteration " + i + "  " + p
		+ ", correct to ± " + tolerance + " ("
		+ decimalPlacesOK + " decimal places)");
        tolerance /= 10; // reduce tolerance for another decimal place
    }

   if (decimalPlacesOK >= decimalPlacesRequired)  return p;
  }
  return -1; // failed to find good enough estimate
}

Your code looks fine to me. I tweaked it a bit to show how extremely predictable the number of iterations will be. When I ran it, the first prediction was off by 1 and all of the others were exact.

public class PiEstimate
{
    public static void main (String args[])
    {
       for (double tolerance = 0.1; tolerance > 0.000001; tolerance *= 0.95)
           estimatePi (tolerance);
    }



    static double estimatePi(double tolerance)
    {
      // pi = 4 - 4/3 + 4/5 - 4/7 + 4/9...etc.

      int expectedNumberOfIterations = (int) (1 / tolerance);
      int maxIterations = expectedNumberOfIterations * 2;

      double p = 4; // current estimate for Pi
      int sign = 1; // alternating sign of terms in series
      for (int i = 1; i < maxIterations; i++) {
        p += (sign = -sign) * 4.0 / (i * 2 + 1);

        if (Math.abs(Math.PI - p) < tolerance) {
            // now accurate within tolerance
            System.out.print ("Estimate = " + p + ", tolerance = " + tolerance);
            System.out.print (", Actual # of iterations = " + i);
            System.out.print (", Expected # of iterations = " + expectedNumberOfIterations);
            System.out.println (", Prediction Error = " + Math.abs (i - expectedNumberOfIterations) / (double) i);
            return p;
        }
      }
      return -1; // failed to find good enough estimate
    }
}

Some of the results below:

Estimate = 3.1416317115126744, tolerance = 3.9058144624792534E-5, Actual # of iterations = 25602, Expected # of iterations = 25602, Prediction Error = 0.0
Estimate = 3.1416297579643837, tolerance = 3.7105237393552906E-5, Actual # of iterations = 26950, Expected # of iterations = 26950, Prediction Error = 0.0
Estimate = 3.1416279033342187, tolerance = 3.524997552387526E-5, Actual # of iterations = 28368, Expected # of iterations = 28368, Prediction Error = 0.0
Estimate = 3.141559166214533, tolerance = 3.34874767476815E-5, Actual # of iterations = 29861, Expected # of iterations = 29861, Prediction Error = 0.0
Estimate = 3.1415608409029026, tolerance = 3.1813102910297426E-5, Actual # of iterations = 31433, Expected # of iterations = 31433, Prediction Error = 0.0
Estimate = 3.141562431152668, tolerance = 3.0222447764782554E-5, Actual # of iterations = 33087, Expected # of iterations = 33087, Prediction Error = 0.0
Estimate = 3.14156394270838, tolerance = 2.8711325376543424E-5, Actual # of iterations = 34829, Expected # of iterations = 34829, Prediction Error = 0.0
Estimate = 3.141619929044609, tolerance = 2.727575910771625E-5, Actual # of iterations = 36662, Expected # of iterations = 36662, Prediction Error = 0.0

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.