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
もう多少の実行効率を犠牲にしても,この可読性と記述性をとってもいいんジャマイカ。