import org.apfloat.*; import java.io.IOException; import java.util.Scanner; import java.io.File; /** * * @author Jake Gunter */ public class PiChudnovskyMultithread { /** * the precision of the calculation; it is set later */ static long precision = 1; /** * the scanner used throughout the program */ Scanner in = new Scanner(System.in); /** * Pi, guaranteed correct (for testing purposes) */ private String piCorrect; //simple constructor public PiChudnovskyMultithread() throws IOException { piCorrect = readPiFile(); } public String readPiFile() throws IOException { Scanner fin = new Scanner(new File("pi.txt")); String piTmp = ""; while(fin.hasNext()) piTmp += fin.nextLine(); return piTmp; } public void validatePi(Apfloat pi) { String piStr = pi.toString(true); int smallerLen = piStr.length() < piCorrect.length() ? piStr.length() : piCorrect.length(); int digitsCorrect = 0; String userPiCorrect = ""; for(int i=0;i0;i=i.subtract(new Apfloat(1))) { Apfloat x = i.compareTo(new Apfloat(1)) == 0 ? new Apfloat(0) : new Apfloat(1); factorialized = factorialized.multiply(i.subtract(x)); } return factorialized; } public static Apfloat inverse(Apfloat num) { return new Apfloat(1).divide(num); } public static Apfloat negpow(Apfloat a, Apfloat b) { if(b.mod(new Apfloat(2)).intValue() == 0) { return ApfloatMath.pow(a.negate(),b); } else return ApfloatMath.pow(a.negate(), b).negate(); } /** * This method handles the thread scheduling and the final summation of pi. * First, it checks the number of available processors with a call to * Runtime.getRuntime().availableProcessors(). Then it creates * an array of {@link chudThread} that will do the actual calculation. *

* Based on a user input of the number of iterations, it spreads that out * over all available chudThread, and sets the field * precision according to the number of calculations. * It also times the calculation. *

* After all threads have finished calculating, it sums the partial sums, * and carries out the final steps needed to calculate pi. Then it displays * pi, along with the amount of time taken for the calculation. * * @throws java.lang.InterruptedException * @throws java.io.IOException */ public void calculatePi() throws InterruptedException, IOException { int numProcs = Runtime.getRuntime().availableProcessors(); chudThread[] calculators = new chudThread[numProcs]; long start = 0; System.out.print("How many iterations? "); int procMult = Integer.parseInt(in.nextLine()) / numProcs; while (procMult <= 0) { System.out.println("That's not a valid number of iterations!"); System.out.print("How many iterations? "); procMult = (in.nextInt()) / numProcs; } precision = procMult * numProcs * 14 + 1 + (procMult * numProcs)/10; System.out.println(precision); for(int i=0;ipiPart. */ @Override public void run() { Apfloat x = new Apfloat(0,precision); Apfloat y = new Apfloat(0,precision); Apfloat a = new Apfloat(0,precision); Apfloat b = new Apfloat(0,precision); Apfloat c = new Apfloat(0,precision); Apfloat bn1 = new Apfloat(-1,precision); Apfloat b6 = new Apfloat(6,precision); Apfloat b13591409 = new Apfloat(13591409,precision); Apfloat b545140134 = new Apfloat(545140134,precision); Apfloat b3 = new Apfloat(3,precision); for(Apfloat i=new Apfloat(start,precision);i.compareTo(new Apfloat(end,precision))<0;i=i.add(new Apfloat(1))) { a = negpow(bn1,i); b = factorial((b6.multiply(i))); c = b13591409.add(b545140134.multiply(i)); x = a.multiply(b.multiply(c)); a = factorial(b3.multiply(i)); b = ApfloatMath.pow(factorial(i),3); c = new Apfloat(3.0/2.0,precision).add(new Apfloat(3,precision).multiply(i)); y = a.multiply(b).multiply(ApfloatMath.pow(new Apfloat(640320,precision),c)); piPart = piPart.add(x.divide(y)); } } } public static void main(String[] args) throws InterruptedException, IOException { new PiChudnovskyMultithread().calculatePi(); } }