倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

円周率の任意精度の値 Scala × spire

円周率の日は過ぎてしまいましたが、円周率関連のお話。

Scala で(実質的には Java で)円周率の値を倍精度で得る方法を実行している画面:


円周率は定数として Math.PI で定義されていますが、こんな取得方法もありますよ、という話。 で、この方法なら、BigDecimal のような任意精度の浮動小数点数が使えれば任意精度で円周率の値が得られるんじゃないかと思ってちょっと試してみました。

残念ながら JavaBigDecimal に対する逆余弦関数は定義されてないので、ここでは Scala と spire を使います。 Scala でライブラリを自動ダウンロードするなら、やっぱり sbt (既にインストール済みですよね?)。 ビルド定義ファイル build.sbt はこんな感じ:

// build.sbt
name := "pi-value"

scalaVersion := "2.11.6"

libraryDependencies in Global += "org.spire-math" % "spire_2.11" % "0.9.1"

適当なディレクトリに「pi-value」ディレクトリを作成してこのビルドファイルを配置し、コマンドライン/PowerShell にて

  1. コマンド「sbt」を実行(sbt の bin ディレクトリへのパスが通ってる必要あり)
  2. コマンド「console」を実行

を行うと

PS C:\Users\...\pi-value> sbt
Java HotSpot(TM) Client VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0
[info] Set current project to pi (in build file:/C:/Users/.../pi-value/)
> console
[info] Starting scala interpreter...
[info]
Welcome to Scala version 2.11.6 (Java HotSpot(TM) Client VM, Java 1.8.0_31).
Type in expressions to have them evaluated.
Type :help for more information.

scala>

さて、これで準備完了。 import 文が1つ必要ですが、あとは簡単に円周率の値が得られます:

scala> import spire.math._
import spire.math._

scala> acos(Real(-1.0))
res0: spire.math.Real = 3.1415926535897932384626433832795028841972

Real は任意精度ですが、文字列として表示する時点で数値が切れてます。 表示桁数を増やすには getString() メソッドを使えばいいんでしょうかね:

scala> acos(Real(-1.0)).getString(100)
res1: String = 3.14159265358979323846264338327950288419716939937510
5820974944592307816406286208998628034825342117068

お手軽。

ちなみに、spire には実数値の円周率が定数として定義されているので、実は逆余弦関数とか持ってくる必要ないようですね:

scala> Real.pi.getString(200)
res2: String = 3.14159265358979323846264338327950288419716939937510
58209749445923078164062862089986280348253421170679
82148086513282306647093844609550582231725359408128
48111745028410270193852110555964462294895493038196

まぁ、現代のプログラミング言語なら、普通は円周率のような定数はきちんと定数で定義されているハズですね。

Javaによるアルゴリズム事典

Javaによるアルゴリズム事典