Question

I'm trying to write a programm, which will calculate PI, using BigDecimal, but it works incorrect. Could yu help me fix mistake, or if you know how to realise Gauss–Legendre algorithm in parallel programm give an example, please. Thanks a lot!

Here's my code:

   import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class PI_Epta implements IParallelPiEx {

    public static void main(String[] args) throws InterruptedException {
        PI_Epta pe = new PI_Epta();
        pe.calculatePi(0, 0);
    }

    @Override
    public BigDecimal calculatePi(int numberOfThreads, int precision) {
        BigDecimal PI = new BigDecimal(0.0);
        ExecutorService es = Executors.newFixedThreadPool(4);
        List<Future<BigDecimal>> tasks = new LinkedList<Future<BigDecimal>>();
        for (int i = 0, n = 0; i < 1000000; n++, i += 2500) {
            PiParallel counter = new PiParallel(i, i + 2499, n, PI);
            Future<BigDecimal> task = es.submit(new PiParallel(i, i + 2499, n, PI));
            tasks.add(task);
        }
        try {
            for (Future<BigDecimal> t : tasks) {
                PI = PI.add(t.get());
            }
            PI = PI.multiply(new BigDecimal(4));
            System.out.println(PI);
            // 3.14159265358979323846
        } catch (Exception e) {
            System.err.println(e);
        }
        es.shutdown();
        return PI;
    }
}



import java.math.BigDecimal;
import java.util.concurrent.Callable;

public class PiParallel implements Callable<BigDecimal> {

    BigDecimal pi = new BigDecimal(0.0);

    int s;
    int f;
    int n;

    public PiParallel(int s, int f, int n, BigDecimal pi) {
        this.s = s;
        this.f = f;
        this.n = n;
        this.pi = pi;
    }   

    @Override
    public BigDecimal call() throws Exception {
        for (; s < f; s++) {
            BigDecimal bd = new BigDecimal((1.0 / (1.0 + 2.0 * s))); 
            bd= bd.multiply(new BigDecimal(((s % 2 == 0) ? 1 : (-1))));
            pi = pi.add(bd);
        }       
        return pi;
    }
}
Was it helpful?

Solution

Since the Gauss–Legendre algorithm defines that A/n+1 is calculated based on A/n, there is no way to parallelize this.

You might want to try the Bailey-Borwein-Plouffe formula instead.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top