0

I need to write an algorithm to find pi, using the formula

pi/4 = 1 - 1/3 + 1/5 - 1/7 +- ...
  • They also want us to make it stop after it has calculated six digits.
  • And does anyone know how to make it round off?

My code currently is:

public class Pi 
{
    public static void main(String[] args) 
    {
        double sum = 1; 
        int sign = -1; 
        double value = 3; 
        while (value < 10_000_000_000) 
        {
            sum = sum + sign / value; 
            value = value + 2; 
            sign = sign * -1; 
        }
        System.out.println("The value of pi is: " + (4 * sum)); 
    }
}

Right now it runs like this

The value of pi is: 3.1415926335902506

I need it to calculate and output 3.141593.

azro
  • 53,056
  • 7
  • 34
  • 70
Melanie
  • 313
  • 2
  • 6
  • 17
  • Possible duplicate of [Calculating Pi Java Program](https://stackoverflow.com/questions/21686036/calculating-pi-java-program) – Berkley Lamb Aug 22 '17 at 20:07
  • 1
    Can you please state whats the problem with your current code? What does it currently output and is it wrong? Or do you only want to know how to implement your two questions but the pi computation itself is already working? – Zabuzard Aug 22 '17 at 20:09
  • 3
    @BerkleyLamb I think the questions aims more for the two highlighted sub-questions and not for the algorithm itself. In this case it is no duplicate to this question. But possibly to two other questions like [How to round a number to n decimal places in Java](https://stackoverflow.com/questions/153724/how-to-round-a-number-to-n-decimal-places-in-java) and [Number of decimal digits in a double](https://stackoverflow.com/questions/6264576/number-of-decimal-digits-in-a-double). – Zabuzard Aug 22 '17 at 20:13
  • You can stop when "it finds 6 digit" because you won't now these 6 digits ^^ you have to do more than 1000 iterations at least to have the 6 correct digits – azro Aug 22 '17 at 20:21
  • The tricky part is determining when it has calculated six digits. There's not a perfectly generic way to determine such a thing. For all values of a (a > 0), there exists a value b such that incrementing b by a will alter all digits of b. So, you're going to need a solution that that wouldn't work for all numbers, but should work for the initial digits of pi. Stopping after a fixed number of iterations is a good approach. I'm guessing 10^7 iterations would be plenty. – mrog Aug 22 '17 at 20:59

1 Answers1

2

Try this code:

/** This method rounds a double to specified number of digits
 * The idea is to multiply the incoming number with the appropriate
 * power of 10, round it to the nearest integer, and then divide it.
 */
public static double round(double x, int n)
{
    double exp = Math.pow(10, n);
    return Math.round(x * exp) / exp;
}

public static void main (String[] args)
{
    double sum = 1; 
    int sign = -1; 
    double value = 3; 

    /* The convergence rate for this series is known,
     * As suggested, 10^7 iterations are enough.
     */
    int nofIterations = Math.pow(10, 7);
    for(int i=0;i<nofIterations;i++) 
    {
        sum = sum + sign / value; 
        value = value + 2; 
        sign = sign * -1; 
    }
    double pseudoPi = 4 * sum;

    /** Now we print both the calculated value and the rounded value
     */
    System.out.println("The calculated value of pi is : " + pseudoPi); 
    System.out.println("The rounded value of pi is    : " + round(pseudoPi, 6));
}

That prints:

The calculated value of pi is : 3.141592663589326
The rounded value of pi is : 3.141593

Joris Schellekens
  • 8,483
  • 2
  • 23
  • 54
  • I believe calling Math.pow in the for loop's condition would impact performance quite a bit. Perhaps this computation should be done on a different line so it isn't repeated with every iteration. – mrog Aug 22 '17 at 21:10
  • Normally the compiler ought to realize that this is a constant, and make the suggested optimization. – Joris Schellekens Aug 22 '17 at 21:12
  • Can you explain your code and state what you have changed? Will be more helpful than a *code only* answer. – Zabuzard Aug 22 '17 at 21:13
  • @JorisSchellekens The compiler can't make that optimization because there's no guarantee that a given method will always return the same value for a given input. I timed `for (int i = 0; i < 10000000; i++) {}` and `for (int i = 0; i < Math.pow(10, 7); i++) {}`. The latter version was an order of magnitude slower. – mrog Aug 22 '17 at 21:25
  • 1
    @mrog Thanks for your input. I made the change to my code-sample. Please upvote. – Joris Schellekens Aug 22 '17 at 22:25