2011-12-03 12 views
8

n桁目にpiをどのように生成できるか知りたかったのですが、私はいくつかの基本的なアイディアを持っています。piからn番目の数字を生成するJava

  1. 使用Math.PIと(それが可能の場合)の精度を高める
  2. ここでもパイを生成だけに使用オイラーの公式、私は精度を高める必要があるだろう(と思う) Euler's formula for PI
  3. スリニヴァサもあります急速な収束のために知られているPIを生成するRamanujanの公式。この式は実装が難しいようです。私は信じて、私はここでも微妙な精度を高めなければならないだろう。
    enter image description here

のでいずれかの方法で、簡単に言えば、私は、n番目の数字が何であるかに応じて、BigDecimalの精度を向上させる必要があります。 BigDecimalの精度をn桁目に上げるにはどうすればよいですか?また、これを行うのがより速くて速い場合は、正しい方向に私を指差してください。

編集:私はPIを生成したいだけです。私は計算に使用したくありません。これはBigDecimalを使ってPIを生成するアイデアを実装する方法についての質問です。

+0

このコードを使用することができますが、実際にパイを生成する必要があるか、計算のためにそれが必要なのですか? –

+0

これは、piの計算の背後にある数学、または 'BigDecimal'の使い方に関する質問ですか? –

+0

私はPI式を実装するためにBigDecimalを使用しています。計算するPIは必要ありません。ただ生成したいだけです。 –

答えて

6
  • Math.PIは、タイプdoubleです。つまり、精度は約15桁で、これはすべてのデータです。 PIの桁が魔法のように表示されることはありません。
  • BigDecimalは、任意の精度を持ちます。 setScale()を使用すると、必要な精度でBigDecimalオブジェクトを作成することができ、ほとんどの算術メソッドは必要に応じて精度を自動的に高めますが、精度が高いほどすべての計算が遅くなります。
  • BigDecimalのsqrt()が組み込まれていないため、Ramanujanの式を実装するのが最も難しいのは皮肉なことに定数係数のsqrt(2)なので、独自に書く必要があります。あなたはBigDecimal

    例えばの精度を高めるためにMathContextを使用する必要が

+0

しかし、平方根については、古き良きヘロン法は、数百万(または10億)の精度でも十分速く収束します。 –

+0

のsqrt(2)部分については、あらかじめ定義された値を使用できませんか? 1.41421356、またはそれは何とか計算を変更する予定ですか? –

+0

@ user681159:PIの価値を "事前定義された値"より正確にしたい場合は、sqrt(2)の桁数を増やす必要があります。 –

3

MathContext mc = new MathContext(1000); 
BigDecimal TWO = new BigDecimal(2, mc); 

それはあなたの計算で使用するすべてのBigDecimal sがMathContextことを使用することが重要です。 Heronのメソッドは、10回の反復で1000桁の精度を、20回の反復で100万桁の精度を与える必要があります。 また、定数BigDecimalをすべて作成します。 26390は、プログラムの開始時に一度だけ。

+0

ヘロンの方法はどういう意味ですか? –

+0

@ user681159 Heronの方法は、後者に精通している場合のために、平方根の場合のNewton-Raphson法と一致します。それ以外の場合は、 'x_(n + 1)= 1/2 *(x_n + a/x_n) 'を介して' sqrt(a) 'に近似する方が良いでしょう。すべてのa> 0と任意の開始値 'x_0> 0'に収束します。あなたがかなり良い近似で始めるならば、各ステップで正しい数字の数が2倍になります。 –

0

あなたは

import java.math.BigDecimal; 
import java.math.RoundingMode; 

public final class Pi { 

private static final BigDecimal TWO = new BigDecimal("2"); 
private static final BigDecimal FOUR = new BigDecimal("4"); 
private static final BigDecimal FIVE = new BigDecimal("5"); 
private static final BigDecimal TWO_THIRTY_NINE = new BigDecimal("239"); 

private Pi() {} 

public static BigDecimal pi(int numDigits) { 

    int calcDigits = numDigits + 10; 

    return FOUR.multiply((FOUR.multiply(arccot(FIVE, calcDigits))) 
    .subtract(arccot(TWO_THIRTY_NINE, calcDigits))) 
    .setScale(numDigits, RoundingMode.DOWN); 
} 

private static BigDecimal arccot(BigDecimal x, int numDigits) { 

BigDecimal unity = BigDecimal.ONE.setScale(numDigits, 
    RoundingMode.DOWN); 
BigDecimal sum = unity.divide(x, RoundingMode.DOWN); 
BigDecimal xpower = new BigDecimal(sum.toString()); 
BigDecimal term = null; 

boolean add = false; 

for (BigDecimal n = new BigDecimal("3"); term == null || 
    term.compareTo(BigDecimal.ZERO) != 0; n = n.add(TWO)) { 

    xpower = xpower.divide(x.pow(2), RoundingMode.DOWN); 
    term = xpower.divide(n, RoundingMode.DOWN); 
    sum = add ? sum.add(term) : sum.subtract(term); 
    add = ! add; 
} 
return sum; 
} 
} 

resource

+0

このコードに問題があり、特定の条件下で無限ループに繋がります;-( –

関連する問題