Domanda

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;
    }
}
È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top