【问题标题】:Error calculating pi using the Chudnovsky algorithm - Java使用 Chudnovsky 算法计算 pi 时出错 - Java
【发布时间】:2014-07-24 16:25:56
【问题描述】:

我一直在尝试编写一个简单的程序来使用 Chudnovsky 算法计算 pi,但是我一直得到错误的值输出。我写的最新代码如下并输出:

9.642715619298075837448823278218780086541162343253084414940204168864066834806498471622628399332216456e11

谁能告诉我哪里出错了。

正如 Peter de Rivaz 指出的那样,我正在丢弃 b 的值并固定,输出现在是:-1.76779979383639157654764981441635890608880847407921749358841620214761790018058‌2-​360012019158247490

    Apfloat sum = new Apfloat(0);

    for(int k = 0; k < n; k++) {
        int thrk= 3*k;

        Apfloat a = ApintMath.factorial(6*k); //(6k)! * (-1)^k
        a = a.multiply(ApintMath.pow(new Apint(-1),k));

        Apfloat b = new Apfloat(545140134);
        b = b.multiply(new Apfloat(k));
        b = b.add(new Apfloat(13591409)); // 13591409 + 545140134k

        Apfloat c = ApintMath.factorial(thrk); // (3k!)

        Apfloat d = ApintMath.factorial(k);
        d = ApfloatMath.pow(d, 3); // (k!)^3
        Apfloat e = new Apfloat(640320); 
        e = ApfloatMath.pow(e,(thrk)); // (640320)^(3k)

        a = a.multiply(b); // a is know the numerator
        c = c.multiply(d).multiply(e); // c in know the denominator 

        Apfloat div = a.divide(c.precision(digits));
        sum = sum.add(div);
    }

    Apfloat f = new Apfloat(10005, digits);// Works out the constant sqrt part
    f = ApfloatMath.sqrt(f);
    f = f.divide(new Apfloat(42709344*100));
    Apfloat pi = ApfloatMath.pow(sum.multiply(f), -1);

    System.out.println(pi);

【问题讨论】:

    标签: java algorithm apfloat


    【解决方案1】:

    问题 1

    有一个问题:

    b.add(new Apfloat(13591409));
    

    这会将 13591409 添加到 b,并丢弃结果。

    试试:

    b = b.add(new Apfloat(13591409));
    

    问题 2

    线路有问题:

    f = f.divide(new Apfloat(42709344*100));
    

    问题是Java中的数字默认是32位整数,所以42709344*100会溢出。

    试试:

    f = f.divide(new Apfloat(42709344*100L));
    

    【讨论】:

    • 谢谢,我可以相信我错过了知道它的输出与以前版本相同的值为 -1.767799793836391576547649814416358906088808474079217493588416202147617900180583600120193e-258>0058360012019158
    【解决方案2】:

    Chudnovsky 算法的分母涉及 640320^(3k + 3/2) - 你只使用 640320^(3k)。

    【讨论】:

    • 我已将 3/2 从序列中拉出,因此是平方根部分
    • 好的,我可以看到 - 因为 640320^(3k + 3/2) = 640320^(3k) * 640320^(3/2) 你可以拉出 640320^(3/2 )...但我没有得到 42709344*100 部分。 640320^(3/2) = 640320*8*sqrt(10005) = 5122560*sqrt(10005)。这不应该是你拉出来的吗?将其与 12 相结合,您的常数因子为 1/(426880*sqrt(10005))... 我这样做对吗?
    • 现在我看到了 1/(426880*sqrt(10005)) == sqrt(10005)/(4270934400)。所以那没关系。不好的是 4270934400 非常接近 2^32。这远远超出了int 可以容纳的范围,实际上可能会显示为负数。
    • 你的权利!,我没有意识到谢谢你现在的工作:)
    猜你喜欢
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    • 2018-03-26
    相关资源
    最近更新 更多