Javaでは多倍長(無限精度)の整数や小数の計算ができます。
小数の割り算については丸めモードを指定する必要があります。丸めモードには次のものがあります。
ROUND_UP
切上げです。絶対値の大きい方に丸めます。ROUND_DOWN
切捨てです。ゼロに近い方に丸めます。ROUND_CEILING
大きい方に丸めます。ROUND_FLOOR
小さい方に丸めます。ROUND_HALF_UP
四捨五入です。最も近い整数が二つあれば,絶対値の大きい方に丸めます。ROUND_HALF_DOWN
四捨五入の変形です。最も近い整数が二つあれば,ゼロに近い方に丸めます。ROUND_HALF_EVEN
標準的な丸め方です。最も近い整数が二つあれば,末位が偶数になる方に丸めます。ROUND_UNNECESSARY
これは丸められては困るときに指定します(デフォルトの挙動)。与えられた精度で正確に表せない場合は ArithmeticException が投げられます。日本の四捨五入は ROUND_HALF_UP
に相当しますが,科学技術計算では ROUND_HALF_EVEN
が最も標準的です。
例として円周率を好きな桁数だけ求めるプログラムを挙げておきます。
import java.io.*; import java.math.*; class Pi { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print("桁数? "); System.out.flush(); int decimals = Integer.parseInt(br.readLine()); long time = System.currentTimeMillis(); BigDecimal two = new BigDecimal("2"); BigDecimal m25 = new BigDecimal("-25"); BigDecimal m57121 = new BigDecimal("-57121"); BigDecimal pi = new BigDecimal("0"); BigDecimal k = new BigDecimal("1"); BigDecimal t = new BigDecimal("-80"); BigDecimal u; while (true) { t = t.divide(m25, decimals, BigDecimal.ROUND_HALF_EVEN); u = t.divide(k, decimals, BigDecimal.ROUND_HALF_EVEN); if (u.signum() == 0) break; pi = pi.add(u); k = k.add(two); } k = new BigDecimal("1"); t = new BigDecimal("956"); while (true) { t = t.divide(m57121, decimals, BigDecimal.ROUND_HALF_EVEN); u = t.divide(k, decimals, BigDecimal.ROUND_HALF_EVEN); if (u.signum() == 0) break; pi = pi.add(u); k = k.add(two); } System.out.println(pi); System.out.println("時間: " + (System.currentTimeMillis() - time) + "ミリ秒"); } }
1997年の時点で,JDK 1.1と486DX2(66MHz)マシンで試したところ,10桁で440ミリ秒,100桁で990ミリ秒,1000桁で7630ミリ秒,10000桁で245740ミリ秒かかりました。
2002年の時点で,J2SDK 1.4とCeleron(500MHz)マシンで試したところ,10桁で25ミリ秒,100桁で43ミリ秒,1000桁で381ミリ秒,10000桁で6950ミリ秒でした。
Last modified: 2005-12-26 10:51:15