Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 6 of 6

Thread: Calculating Pi to more digits?

  1. #1
    Member
    Join Date
    Feb 2013
    Posts
    78
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default Calculating Pi to more digits?

    Hey guys! So I have been messing around with calculating pi and I have gotten to the point where I have a loop running from 0 to long.max value. I am using the fallowing infinite series:
    pi = 4/1 + 4/3 - 4/5 + 4/7 ...
    I am wondering a few things. First of all, I tried using BigDecimal and BigInteger to do this and it didn't really work out... I am wondering, how do I convert this:
    double pi = 0.0;
    				long divisor = 1;
    				boolean positive = false;
     
    				for(long i = 0; i < Long.MAX_VALUE; i++)
    				{
    					double n = ((double)4 / (double)divisor);
    					if(positive)
    						pi -= n;
    					else
    						pi += n;
    					positive = !positive;
    					divisor += 2;
    				}
     
    				print("Pi calculated as: " + pi);
    To use BigInteger/Decimal? Also, are there any more accurate infinite series' that are more accurate AND are just as easy or almost as easy to implement?


  2. #2
    Super Moderator jps's Avatar
    Join Date
    Jul 2012
    Posts
    2,642
    My Mood
    Daring
    Thanks
    90
    Thanked 263 Times in 232 Posts

    Default Re: Calculating Pi to more digits?

    Read the API for the BigInteger class and see which methods suit your needs.
    Post the code with your attempt if you have problems.
    Ask a specific question if you have one, right now your question just kind of asks for someone to convert it to use BigInteger for you.

  3. #3
    Super Moderator pbrockway2's Avatar
    Join Date
    Jan 2012
    Posts
    987
    Thanks
    6
    Thanked 206 Times in 182 Posts

    Default Re: Calculating Pi to more digits?

    And for an overview of series approximations Wikipedia is a good first stop.

    A factoid for anyone too idle to follow the link: the currently calculated precision is 10 trillion digits using Chudnovsky's algorithm. It looks like it should be reasonably easily implemented. Certainly more easily implemented than understood!

  4. #4
    Member
    Join Date
    Feb 2013
    Posts
    78
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default Re: Calculating Pi to more digits?

    Due to my age, I haven't even learned most of that maths... I have no idea what the majority of that stuff means. Thus, I have no idea how to implement it. One question that isn't related to the algorithm however, how could I implement something that would calculate pi with multiple threads or multiple workers? I have ideas but I don't know how I could really make them work together properly. I would love to figure that out.

  5. #5
    Super Moderator pbrockway2's Avatar
    Join Date
    Jan 2012
    Posts
    987
    Thanks
    6
    Thanked 206 Times in 182 Posts

    Default Re: Calculating Pi to more digits?

    jps called it correctly, I think. Rather than threads, think about how you might implement the formula you have using BigDecimal/Integer.

    To begin with write some programs that simply add/subtract/multiply/divide decimal values. Once those are working as you intend you can use the arithmetic operations on decimal values in your pi program.

    Ask if you get stuck. It really doesn't matter what code you come up with, but people can only really help with that code. If someone posts *their* pi calculating code, that's just robbed you of the fun of writing your own.

  6. #6
    Member
    Join Date
    Jun 2012
    Location
    Left Coast, USA
    Posts
    451
    My Mood
    Mellow
    Thanks
    1
    Thanked 97 Times in 88 Posts

    Default Re: Calculating Pi to more digits?

    Quote Originally Posted by sci4me View Post
    ...BigDecimal...
    That's probably a good thing to investigate, since you are wanting more precision in the terms than Java's built-in double precision variables can give you.

    Quote Originally Posted by sci4me View Post
    ...and BigInteger to do this and it didn't really work out...
    I don't see the need for BigInteger. Every term is a floating point number. When you add successive terms you get an approximation that is a floating point number. So, just do everything with floating point arithmetic. Concentrate on BigDecimal (or other arbitrary precision floating point packages that you might run across).

    What do you mean it didn't "work out"? It "works out" if you "do it right."
    Quote Originally Posted by sci4me View Post
    I am wondering, how do I convert this...

    OK, I'll give it a shot:
    • Create BigDecimal objects for numerator, denominator, sum, and term with initial values 4.0, 1.0, 0.0, and 4.0

    • You very well might find use for a BigDecimal object initialized to 2.0, so that you can add 2.0 to the denominator each time through the loop. (I would probably call it bigTwo, or some such thing.)

    • Declare a boolean variable positiveSign that will make it easy to alternate the sign of the term that contributes to the sum each time through the loop. initialize it to true, since the first term will be added to sum inside the loop.

    • Decide how many terms you would like to use in your approximation. Start with a small number so that you can verify the accuracy of the term and the cumulative sum at each step of the program.

    • Decide how many decimal places of precision for which you want the divisions to be approximated and create a MathContext object for this value.


    Here's pseudo-code for the main() method:

    Declare and initialize int variables numTerms and precision.
     
    Create a MathContext object with your value of precision.
     
    Declare and initialize BigDecimal objects
        bigTwo        Initial value 2.0
        sum           Initial value 0.0
        numerator     Initial value 4.0
        denominator   Initial value 1.0
        term          Initial value numerator divided by denominator
     
    Declare and initialize the boolean variable:
        positiveSign  Initial value true
     
    Here's the loop:
    for (int i = 0; i < numTerms; i++)
    BEGIN LOOP
        IF positiveSign THEN
            sum = sum plus term  // Use BigDecimal add() method
        ELSE
            sum = sum minus term // Use BigDecimal subtract() method
        END IF
     
        Print out value of sum.
     
        // Calculate value of next term.  Note that for alternating
        // convergent series, truncation error is less than or equal
        // to the absolute value of the next term.
     
        denominator = denominator plus 2  // Use BigDecimal add(bigTwo)
        term = numerator divided by denominator // Use BigDecimal divide() with mc context
        Print value of term.  (This is an upper bound of the error of the sum so far.)
     
        Set positiveSign equal to !positiveSign
    END LOOP

    Now, suppose we want 10 decimal digit precision to be maintained for the division operations, and suppose we want to print the first four partial sums

    The output might look like:
    Partial sum 1:
      Approx: 4
      |Err| < 1.333333333
     
    Partial sum 2:
      Approx: 2.666666667
      |Err| < 0.8
     
    Partial sum 3:
      Approx: 3.466666667
      |Err| < 0.5714285714
     
    Partial sum 4:
      Approx: 2.8952380956
      |Err| < 0.4444444444

    It's very important that you verify the validity of these values before going on to bigger and better things.

    If you like it so far (that is, if you think it is giving the results that you expected), then, try something like precision = 100 decimal digits and ten thousand terms.

    Here are the last few of the 10000 partial sums:
    Partial sum 9997:
      Approx: 3.1416926835985457141409486174398088488002669437238313470218194294878764930799823190509708376226708769092
      |Err| < 0.0002000500125031257814453613403350837709427356839209802450612653163290822705676419104776194048512128032
     
    Partial sum 9998:
      Approx: 3.1414926335860425883595032560994737650293242080399103667767581641715474108094146771404932182178196641060
      |Err| < 0.0002000300045006751012651897784667700155023253488023203480522078311746762014302145321798269740461069160
     
    Partial sum 9999:
      Approx: 3.1416926635905432634607684458779405350448265333887126871248103720027220870108448916726730451918657710220
      |Err| < 0.0002000100005000250012500625031251562578128906445322266113305665283264163208160408020401020051002550128
     
    Partial sum 10000:
      Approx: 3.1414926535900432384595183833748153787870136427441804605134798054743956706900288508706329431867655160092
      |Err| < 0.0001999900004999750012499375031248437578121093945302734863256837158142092895355232238388080595970201490

    See how it goes?

    The program has done a lot of work. (Who cares? That's why we have computers, right? Let them do the work.)

    However...

    After ten thousand terms, the approximation is only correct to four significant decimal digits.

    The problem isn't with the "accuracy" of the infinite series you are using. It's "accurate." The problem is that it will take a lot of terms (a whole lot of terms) to converge to a value that has more precision than the 16 or 17 significant decimal digits that you get with double precision Java variables.

    Exercise for the student:

    How many terms of the series will be required to get an approximate value of Pi that is accurate to 20 significant decimal digits.

    That's 19 decimal places accuracy.

    Question:
    Given that the absolute error after n terms is bounded by the value of the next term (i.e. 4/(2*n+1)), how many terms will be required to guarantee that the error is less than 0.5 times 10 to the -19 power?

    Short answer:
    A bunch.

    Intermediate answer:
    A really big bunch.


    Next question:
    Is there a better way?

    Answer:
    There are about a million ways. Maybe more. It happens that your series, equal to the Taylor series expansion of 4*arctan(1.0), is one of the slowest of them all. Really slow.

    People have been developing faster-converging approximations for hundreds of years. Maybe more. If you are really interested, then do some research and knuckle down to learning some math.

    Maybe start here: Numerical Approximations of Pi

    If you think it's better to spend your time doing something else until you have been exposed to enough mathematical rigor to read the literature, then that's OK too.


    Cheers!

    Z

Similar Threads

  1. Changing digits to words
    By Spanky_10 in forum What's Wrong With My Code?
    Replies: 0
    Last Post: March 5th, 2013, 04:57 PM
  2. User entry needs to be exactly 5 digits
    By tyneframe in forum Java Theory & Questions
    Replies: 4
    Last Post: September 29th, 2012, 09:54 PM
  3. All Digits only
    By kram in forum What's Wrong With My Code?
    Replies: 3
    Last Post: October 28th, 2011, 03:16 PM
  4. Separating Digits in a String
    By Staticity in forum What's Wrong With My Code?
    Replies: 3
    Last Post: October 3rd, 2011, 06:39 AM
  5. Remove last digits of an IP address.
    By Jonathan_C in forum Algorithms & Recursion
    Replies: 1
    Last Post: November 15th, 2010, 12:55 PM