0

私は最近、Math.BigDecimal で動作する基本的な Pi 電卓を作成しました。テキスト ファイルに出力し、非常に高速に計算しますが、BigDecimal でも限界があります。さらに正確な数値の場合、基本的なコードはどうなるのだろうと思っていました(実際にそれを必要とするコードはありません)。パイコードは次のとおりです。

    package mainPack;
    import java.io.IOException;
    import java.math.BigDecimal;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.util.Scanner;
    public class Main {
    public static BigDecimal piDigCalc(int i){
        double o = (double)i;
        BigDecimal ret = new BigDecimal((1/(Math.pow(16.0D, o))*((4/((8*o) + 1))-(2/((8*o) + 4))-(1/((8*o) + 5))-(1/((8*o)+6))))); //Just the code for a hexdigit of Pi.
        return ret;
    }
    public static void main(String[] args) throws IOException {
        System.out.println("Enter accuracy:");
        Scanner s = new Scanner(System.in);
        int acc = s.nextInt();
        s.close();
        BigDecimal Pi = new BigDecimal(0);
        for(int i = 0; i < acc; i++){
                Pi = Pi.add(piDigCalc(i));
        }
        Path file = Paths.get("C:\\tmp\\PI.txt");
        String pi = "" + Pi;
        Files.write(file, pi.getBytes());
            System.out.println("File has been saved at "+ file.toString());
    }
}
4

1 に答える 1

0

piDigCalc完全に任意の精度値を使用するように関数を書き直しました。ideone で実行されていることがわかります(1300 は、ideone の 15 秒の制限時間内で完了することができる最大の精度でした)。

これは決して最適化されたものではありません。コード内の数学を bigdecimals に逐語的に変換しただけです。

実際には値に精度制限があることに気付くかもしれませんが、これは部分的には、巨大な制限を設定するとランタイムが大幅に増加するためです。私が設定した制限は、提供された精度でスケーリングします。

ideone が爆発した場合に備えて、コードは次のpiDigCalcとおりです。

public static BigDecimal piDigCalc(int _i, int x){
    BigDecimal
        i = BigDecimal.valueOf(_i),
        a = SIXTEEN.pow(_i),
        b = EIGHT.multiply(i),
        c = ONE.divide(a, x, BigDecimal.ROUND_HALF_EVEN),
        d = b.add(ONE), // b + 1
        e = b.add(FOUR), // b + 4
        f = e.add(ONE), // b + 5
        g = f.add(ONE), // b + 6
        h = FOUR.divide(d, x, BigDecimal.ROUND_HALF_EVEN),
        j = TWO.divide(e, x, BigDecimal.ROUND_HALF_EVEN),
        k = ONE.divide(f, x, BigDecimal.ROUND_HALF_EVEN),
        l = ONE.divide(g, x, BigDecimal.ROUND_HALF_EVEN),
        m = h.subtract(j).subtract(k).subtract(l),
        n = c.multiply(m);

    return n;
}

定数ONE, TWO, FOUR, EIGHT, SIXTEENはクラスに対して静的に定義され、正確な整数値を持ちます ( ONEBigDecimal にも定数として存在します)。

于 2013-07-10T21:41:49.993 に答える