如何使用Harmonic系列获得更高的PI精度

时间:2013-07-09 20:24:43

标签: java pi

试图回到Java并决定解决PI问题。所以我根据Harmonic系列制作了这个程序:

public static void main(String [] args)
{   
    double denominator = 1.0;
    double tempValue;
    double PI = 0.0;

    // End point for program
    double stopPoint = 1234.5;

    for( int i = 1; i < stopPoint; i++  )
    {
        tempValue = Math.sqrt( (1/(denominator*denominator))/6 );

        PI = PI + tempValue;
        denominator = denominator + 1.0;
    }
    System.out.println( "PI = " + PI );

应用程序打印出来:

PI = 3.1417306496998294

所以你可以看到它温和地工作。但是当我更改stopPoint值时,我根本没有改变精度。

例如,将其更改为1234.75会给出相同的答案 - 或者print无法显示确切的值?如果是这样,打印出这些值的最佳方法是什么?

由于

编辑

我已添加此代码作为对上面发布的代码的更改。一些更改包括使用Big Decimal并包含while loop而不是for

import java.math.BigDecimal;
import java.math.MathContext;

public class MyPI 
{
final static BigDecimal ONE = new BigDecimal(1);
final static BigDecimal SIX = new BigDecimal(6);

public static void main(String [] args)
{
    BigDecimal deno, temp, tempPI;

    int start, end;
    start = 1;
    end = 500000;
    temp = new BigDecimal(0);

    // Starting denominator point
    deno = ONE;

    while( start < end )
    {
        // Without precision and rounding mode, it will try to return a
        // never ending number
        temp = temp.add( ONE.divide(deno.pow(2),MathContext.DECIMAL64) );
        deno = deno.add(ONE);

        start = start + 1;
    }
    tempPI = temp.multiply(SIX);

    // Need to convert to double for square root
    double PI = Math.sqrt( tempPI.doubleValue() );
    System.out.println( "PI: " + PI );
}
}

这会产生以下结果:

PI: 3.1415907437318054

感谢大家的帮助 - 可能会添加一个计时器来跟踪执行此操作所需的时间。

4 个答案:

答案 0 :(得分:2)

我一直在使用BigDecimal类型而不是double,但我遇到了一些障碍 - 平方根。

不要采用每个术语的平方根。如此example所示,添加series的术语,其具有精确的和π 2 / 6。当你的循环终止时,乘以6然后然后取一个平方根。

答案 1 :(得分:1)

如果您想要更高的精度,可以使用Java的BigDecimal

答案 2 :(得分:1)

使用Java BigDecimal而不是具有有限精度的Double。

答案 3 :(得分:1)

BigDecimal类可以为你提供“任意精度的带符号十进制数”,这就是你想要的,尽管BigDecimal的实例比文字更难处理,实际上这个类工作很快,可以用来相当准确地完成你需要的工作。

仅仅为了您的信息,使用谐波系列计算Pi是非常低效的,但我理解这是一个有趣的程序或学习新的东西。