Search code examples
javabigdecimalpi

How to use in Java big double numbers?


I've found a solution for calculating number of Pi by using BBS algorithm. But I encountered a problem. I'm missing a precision if using a double variable. Is there any suggestion to fix it?

Here is my code:

public class Pi {
    public static void main(String[] args) {
        int n = 5;

        for (int k = 0; k < n; k++) {
            int a0 = (int) Math.pow(16, k);

            double a1 = (double) 4 / (8 * k + 1);
            double a2 = (double) 2 / (8 * k + 4);
            double a3 = (double) 1 / (8 * k + 5);
            double a4 = (double) 1 / (8 * k + 6);

            double a5 = a1 - a2 - a3 - a4;
            double a6 = (double) 1 / a0;
            double elem = a5 * a6;

            System.out.println(new BigDecimal(elem));
        }
    }
}

Solution

  • If you need the precision of BigDecimal, you need to use it for all calculations. It is not sufficient to convert the result from double to BigDecimal at the end, because the precision is gone by then.

    You need to convert all your aX variables to BigDecimal, and replace operators with calls to the corresponding methods of BigDecimal class:

    BigDecimal pi = BigDecimal.ZERO;
    for (int k = 0; k < n; k++) {
        BigDecimal a0 = new BigDecimal(16).pow(k);
        BigDecimal a1 = new BigDecimal(4).divide(new BigDecimal(8*k+1), 20, RoundingMode.HALF_UP);
        BigDecimal a2 = new BigDecimal(2).divide(new BigDecimal(8*k+4), 20, RoundingMode.HALF_UP);
        BigDecimal a3 = new BigDecimal(1).divide(new BigDecimal(8*k+5), 20, RoundingMode.HALF_UP);
        BigDecimal a4 = new BigDecimal(1).divide(new BigDecimal(8*k+6), 20, RoundingMode.HALF_UP);
        BigDecimal a5 = a1.subtract(a2).subtract(a3).subtract(a4);
        BigDecimal a6 = BigDecimal.ONE.divide(a0, 20, RoundingMode.HALF_UP);
        pi.add(a5.multiply(a6));
        System.out.println(pi);
    }
    

    Demo on ideone.