Calculate PI To Arbitrary Precision (Sample Java Code)

By Angsuman Chakraborty, Gaea News Network
Tuesday, November 13, 2007

Sample Java code to calculate PI to arbitrary precision. This uses Machin’s formula: pi/4 = 4*arctan(1/5) - arctan(1/239).

Notes:
1. Run Pi with a positive integer precision value. For example to calculate PI to 10 decimal places run:
java Pi 10
2. There are other algorithms and even better ones to calculate PI too. This is just an example. I use it to load test my server.
3. Try running with 1 million (1000000) to give your server a good workout :)


import java.math.BigDecimal;

public class Pi {
    public static void main(String args[]) throws NumberFormatException {
        int digits = Integer.parseInt(args[0]);
        String pi = computePi(digits).toString();
        int freq[] = new int[10];
        for(int i = 0;i < 10;i++) freq[i] = 0;
        int c;
        for(int i = 0;i < pi.length();i++) {
            c = pi.charAt(i);
            if(c == '.') continue;
            c -= '0';
            freq[c]++;
        }
        for(int i = 0;i < 10;i++) {
            System.out.println("" + i + " " + freq[i]);
        }
    }
    /** constants used in pi computation */
    private static final BigDecimal FOUR = BigDecimal.valueOf(4);

    /** rounding mode to use during pi computation */
    private static final int roundingMode = BigDecimal.ROUND_HALF_EVEN;

    /**
     * Compute the value of pi to the specified number of
     * digits after the decimal point.  The value is
     * computed using Machin's formula:
     *
     *          pi/4 = 4*arctan(1/5) - arctan(1/239)
     *
     * and a power series expansion of arctan(x) to
     * sufficient precision.
     */
    public static BigDecimal computePi(int digits) {
        int scale = digits + 5;
        BigDecimal arctan1_5 = arctan(5, scale);
        BigDecimal arctan1_239 = arctan(239, scale);
        BigDecimal pi = arctan1_5.multiply(FOUR).subtract(
                                  arctan1_239).multiply(FOUR);
        return pi.setScale(digits,
                           BigDecimal.ROUND_HALF_UP);
    }
    /**
     * Compute the value, in radians, of the arctangent of
     * the inverse of the supplied integer to the specified
     * number of digits after the decimal point.  The value
     * is computed using the power series expansion for the
     * arc tangent:
     *
     * arctan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 +
     *     (x^9)/9 ...
     */
    public static BigDecimal arctan(int inverseX,
                                    int scale)
    {
        BigDecimal result, numer, term;
        BigDecimal invX = BigDecimal.valueOf(inverseX);
        BigDecimal invX2 =
            BigDecimal.valueOf(inverseX * inverseX);

        numer = BigDecimal.ONE.divide(invX,
                                      scale, roundingMode);

        result = numer;
        int i = 1;
        do {
            numer =
                numer.divide(invX2, scale, roundingMode);
            int denom = 2 * i + 1;
            term =
                numer.divide(BigDecimal.valueOf(denom),
                             scale, roundingMode);
            if ((i % 2) != 0) {
                result = result.subtract(term);
            } else {
                result = result.add(term);
            }
            i++;
        } while (term.compareTo(BigDecimal.ZERO) != 0);
        return result;
    }
}

Note: The code has been adapted from a java.sun example.

Discussion
December 21, 2009: 9:23 am

hi,,nice work,i just want to say thanks…


david bandel
January 30, 2009: 6:26 am

gives array out of bounds exception. not worth my time.

probably less efficient than my own pi-calculator anyways.

learn some java before you go posting code on the interweb. lolz.

YOUR VIEW POINT
NAME : (REQUIRED)
MAIL : (REQUIRED)
will not be displayed
WEBSITE : (OPTIONAL)
YOUR
COMMENT :