java 找到 pi 的值直到 50 位

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5566187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 11:41:41  来源:igfitidea点击:

find the value of pi till 50 digits

javamathpi

提问by Nandha

I want to calculate the value of PI till 50 digits.

我想计算 PI 的值直到 50 位。

How to do this in java for 50 decimal places?

如何在java中为50个小数位做到这一点?

采纳答案by Nandha

public class PiReCalc {
  public static final int N = 1000; // # of terms
   public static void main(String[] args) {
  BigDecimal sum = new BigDecimal(0);      // final sum
  BigDecimal term = new BigDecimal(0);           // term without sign
  BigDecimal sign = new BigDecimal(1.0);     // sign on each term

  BigDecimal one = new BigDecimal(1.0);
  BigDecimal two = new BigDecimal(2.0);

  for (int k = 0; k < N; k++) {
     BigDecimal count = new BigDecimal(k); 
     //term = 1.0/(2.0*k + 1.0);
     BigDecimal temp1 = two.multiply(count);
     BigDecimal temp2 = temp1.add(one);
     term = one.divide(temp2,50,BigDecimal.ROUND_FLOOR);

     //sum = sum + sign*term;
     BigDecimal temp3 = sign.multiply(term);
     sum = sum.add(temp3);

     sign = sign.negate();
  }
  BigDecimal pi = new BigDecimal(0);
  BigDecimal four = new BigDecimal(4);
  pi = sum.multiply(four);

  System.out.println("Calculated pi (approx., " + N + " terms and 50 Decimal Places): " + pi);
  System.out.println("Actual pi: " + Math.PI);
   }
}

The output is

输出是

Calculated pi (approx., 1000 terms and 50 Decimal Places): 3.14059265383979292596359650286939597045138933077984
Actual pi: 3.141592653589793

计算的 pi(大约,1000 项和 50 个小数位):3.14059265383979292596359650286939597045138933077984实际 pi:3.14189279535

回答by flolo

You cant do that with default data types, as you need for 50 digits: 50 / log(2) * log(10) = 166 bits. Here BigDecimal is one type you could use instead. But you should have in mind, that 22/7 is just an approximation of pi, and to get it right for 50 digits you need much better formula (e.g. Monte-Carlo method, taylor series, ...).

您不能使用默认数据类型执行此操作,因为您需要 50 位数字:50 / log(2) * log(10) = 166 位。这里 BigDecimal 是您可以使用的一种类型。但是您应该记住,22/7 只是 pi 的近似值,并且要使其正确处理 50 位数字,您需要更好的公式(例如蒙特卡罗方法、泰勒级数等)。

回答by jzd

You are using a double variable and instead should use something that has a greater precision. Look into the BigDecimalclass.

您正在使用双变量,而应该使用具有更高精度的变量。进BigDecimal班看看。

回答by hoford

This is a quick and dirty implementation of Bellard's formula bigPi(200,2000) is good for over 500 decimal places in 75ms.

这是 Bellard 公式 bigPi(200,2000) 的快速而肮脏的实现,在 75 毫秒内可以保留 500 多个小数位。

public static BigDecimal bigPi(int max,int digits) {
    BigDecimal num2power6 = new BigDecimal(64);
    BigDecimal sum = new BigDecimal(0);
    for(int i = 0; i < max; i++ ) {
        BigDecimal tmp;
        BigDecimal term ; 
        BigDecimal divisor;
        term = new BigDecimal(-32); 
        divisor = new BigDecimal(4*i+1); 
        tmp =  term.divide(divisor, digits, BigDecimal.ROUND_FLOOR);
        term = new BigDecimal(-1); 
        divisor = new BigDecimal(4*i+3); 
        tmp = tmp.add(term.divide(divisor, digits, BigDecimal.ROUND_FLOOR));
        term = new BigDecimal(256); 
        divisor = new BigDecimal(10*i+1); 
        tmp = tmp.add(term.divide(divisor, digits, BigDecimal.ROUND_FLOOR));
        term = new BigDecimal(-64); 
        divisor = new BigDecimal(10*i+3); 
        tmp = tmp.add(term.divide(divisor, digits, BigDecimal.ROUND_FLOOR));
        term = new BigDecimal(-4); 
        divisor = new BigDecimal(10*i+5); 
        tmp = tmp.add(term.divide(divisor, digits, BigDecimal.ROUND_FLOOR));
        term = new BigDecimal(-4); 
        divisor = new BigDecimal(10*i+7); 
        tmp = tmp.add(term.divide(divisor, digits, BigDecimal.ROUND_FLOOR));
        term = new BigDecimal(1); 
        divisor = new BigDecimal(10*i+9); 
        tmp = tmp.add(term.divide(divisor, digits, BigDecimal.ROUND_FLOOR));
        int s = ((1-((i&1)<<1)));
        divisor = new BigDecimal(2); 
        divisor = divisor.pow(10*i).multiply(new BigDecimal(s));
        sum = sum.add(tmp.divide(divisor, digits, BigDecimal.ROUND_FLOOR));
    }
    sum = sum.divide(num2power6,digits, BigDecimal.ROUND_FLOOR);
    return sum;

}

回答by Landei

Here is the break through paper of Bailey, Borwein and Plouffe: http://oldweb.cecm.sfu.ca/projects/pihex/p123.pdf

这是 Bailey、Borwein 和 Plouffe 的突破性论文:http: //oldweb.cecm.sfu.ca/projects/pihex/p123.pdf

In the meantime, even faster formulas (following the same principles) were found: http://en.wikipedia.org/wiki/Bellard%27s_formula

与此同时,发现了更快的公式(遵循相同的原则):http: //en.wikipedia.org/wiki/Bellard%27s_formula