Groovyで円周率を求めてみた

えー,数学的なことはあたしに聞かないでください。
きしださんが

けど、BigDecimalのプログラムめんどすぎ泣ける。Scala使ったほうがいいね。

2008-11-16

って言ってたんで,ScalaはわかんないからGroovyで試してみたよ。だってGroovy,ほっときゃ数値はBigDecimalだかんね。→http://groovy.codehaus.org/Groovy+Math


書いたコードはこんなん。

def sig = 1.0      // .0 付けて明示的にBigDecimalにしてる。
def a = 0.0        // 1 や 0 だとIntegerになったはず。
def b = 0.0
def s1 = 1.0 / 5
def s2 = 1.0 / 239

def start = System.nanoTime();
(1..140).step(2) { i ->
 a += sig * s1 / i
 b += sig * s2 / i
 s1 /= 5 * 5
 s2 /= 239 * 239
 sig *= -1
}
println ((System.nanoTime() - start) / 1000 / 1000 / 1000)
println (a * 16 - b * 4)

こんだけだと,結果はこうなった。

3.14159265280


先のコードはそのままで,きしださんとこのBigDecimal版と同じようにするために,ちょっとズルして,先頭にこんなコードを加える。

import java.math.MathContext

BigDecimal.metaClass.div = { BigDecimal x ->
 delegate.divide(x, new MathContext(100))
}
BigDecimal.metaClass.multiply = { BigDecimal x ->
 delegate.multiply(x, new MathContext(100))
}
BigDecimal.metaClass.minus = { BigDecimal x ->
 delegate.subtract(x, new MathContext(100))
}
BigDecimal.metaClass.plus = { BigDecimal x ->
 delegate.add(x, new MathContext(100))
}


そすっと,結果はこうなった(10桁ごとにスペース入れてます)。

3.1415926535 8979323846 2643383279 5028841971 6939937510 
5820974944 5923078164 0628620899 8628034825 342117065


もう多少の実行効率を犠牲にしても,この可読性と記述性をとってもいいんジャマイカ