문제

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;
    }
}
도움이 되었습니까?

해결책

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top