1. ホーム
  2. java

[解決済み] Javaで大きな倍数を使用するには?

2022-02-15 06:09:35

質問事項

BBSアルゴリズムを使って円周率を計算する方法を見つけました。しかし、問題が発生しました。double変数を使用すると精度が足りません。これを修正するために何か提案はありますか?

以下は私のコードです。

public class Pi {
    public static void main(String[] args) {
        int n = 5;

        for (int k = 0; k < n; k++) {
            int a0 = (int) Math.pow(16, k);

            double a1 = (double) 4 / (8 * k + 1);
            double a2 = (double) 2 / (8 * k + 4);
            double a3 = (double) 1 / (8 * k + 5);
            double a4 = (double) 1 / (8 * k + 6);

            double a5 = a1 - a2 - a3 - a4;
            double a6 = (double) 1 / a0;
            double elem = a5 * a6;

            System.out.println(new BigDecimal(elem));
        }
    }
}

解決方法は?

の精度が必要な場合 BigDecimal は、すべての計算で使用する必要があります。の結果を変換するだけでは十分ではありません。 double から BigDecimal を最後にすると、その時点で精度が落ちてしまうからです。

をすべて変換する必要があります。 aX 変数を BigDecimal の対応するメソッドの呼び出しで演算子を置き換えます。 BigDecimal クラスがあります。

BigDecimal pi = BigDecimal.ZERO;
for (int k = 0; k < n; k++) {
    BigDecimal a0 = new BigDecimal(16).pow(k);
    BigDecimal a1 = new BigDecimal(4).divide(new BigDecimal(8*k+1), 20, RoundingMode.HALF_UP);
    BigDecimal a2 = new BigDecimal(2).divide(new BigDecimal(8*k+4), 20, RoundingMode.HALF_UP);
    BigDecimal a3 = new BigDecimal(1).divide(new BigDecimal(8*k+5), 20, RoundingMode.HALF_UP);
    BigDecimal a4 = new BigDecimal(1).divide(new BigDecimal(8*k+6), 20, RoundingMode.HALF_UP);
    BigDecimal a5 = a1.subtract(a2).subtract(a3).subtract(a4);
    BigDecimal a6 = BigDecimal.ONE.divide(a0, 20, RoundingMode.HALF_UP);
    pi.add(a5.multiply(a6));
    System.out.println(pi);
}

IDEONEでのデモ .