The algorithm to calculate PI is based on "http://stackoverflow.com/questions/12449430/how-did-the-following-piece-of-java-code-calculate-the-digits-of-pi".
Source code
Java
import java.math.BigDecimal; import java.math.BigInteger; public class PiCalculator { public static void main(String[] args) { int precision = Integer.parseInt(args[0]); BigDecimal total = BigDecimal.ZERO; for (int i = 0; i < precision; i++) { total = total.add(getStep(i, precision)); } System.out.println("Pi = " + total); } public static BigDecimal getStep(int k, int scale) { BigInteger base = BigInteger.valueOf(16).pow(k); int k1 = 8 * k + 1; int k4 = 8 * k + 4; int k5 = 8 * k + 5; int k6 = 8 * k + 6; base = base.multiply(BigInteger.valueOf(k1)); base = base.multiply(BigInteger.valueOf(k4)); base = base.multiply(BigInteger.valueOf(k5)); base = base.multiply(BigInteger.valueOf(k6)); int numerator = 4 * k4 * k5 * k6 - 2 * k1 * k5 * k6 - k1 * k4 * k6 - k1 * k4 * k5; return BigDecimal.valueOf(numerator).divide(new BigDecimal(base), scale - 1, BigDecimal.ROUND_HALF_UP); } }
Groovy
def scale = Integer.parseInt(args[0]) BigDecimal total = BigDecimal.ZERO for (i in 0..scale-1) { total = total.add(getStep(i, scale)) } println "Pi = " + total def getStep(int k, int scale) { BigInteger base = BigInteger.valueOf(16).pow(k); int k1 = 8 * k + 1; int k4 = 8 * k + 4; int k5 = 8 * k + 5; int k6 = 8 * k + 6; base = base.multiply(BigInteger.valueOf(k1)); base = base.multiply(BigInteger.valueOf(k4)); base = base.multiply(BigInteger.valueOf(k5)); base = base.multiply(BigInteger.valueOf(k6)); int numerator = 4 * k4 * k5 * k6 - 2 * k1 * k5 * k6 - k1 * k4 * k6 - k1 * k4 * k5; return BigDecimal.valueOf(numerator).divide(new BigDecimal(base), scale - 1, BigDecimal.ROUND_HALF_UP); }
Clojure
Create Project
$ lein new calc-pi;cd calc-pi;cat project.clj
...
:dependencies [[org.clojure/clojure "1.5.1"] [org.clojure/math.numeric-tower "0.0.2"]])
core.clj
(defn calc-pi [k] (convert-decimal (calc-pi-expt k) k)) (defn convert-decimal "Convert a ratio to decimal with precision prec" [source prec] (with-precision prec (/ (bigdec (numerator source)) (denominator source)))) (defn calc-pi-expt [k] (reduce + (map step-expt (range k)))) (require '[clojure.math.numeric-tower :as math]) (defn step-expt [k] (/ (- (/ 4 (+ ( 8 k) 1)) (/ 2 (+ ( 8 k) 4)) (/ 1 (+ ( 8 k) 5)) (/ 1 (+ ( 8 k) 6))) (math/expt 16 k)))
Calculate
Java
$ javac PiCalculator.java
$ time java PiCalculator 500
=> 0.25s
This value doesn't include compilation time!
$ /usr/bin/time -p sh -c 'javac PiCalculator.java;java PiCalculator 500'
=> 0.87
Clojure
(time (calc-pi 500)) => 0.8s
Groovy
$ time groovy calcPi.groovy 500
=> 1.09s