实施算法来计算PI

实施算法来计算PI

问题描述:

我正在实施这一算法:实施算法来计算PI

The Algorithm

应返回皮。 (3.14159265358997 ......)

但是,它返回:3465.083806164093990270538663167216844483674020103009669083093329738829995996594112113602427583738613083176438797806351846300982902722428833574050222861187694471396267405291545817609533108750954365354212195605941387622559085119176400306480675261092997442439408294603789105964390454395204651576460276909255907631487405486520824235883248771043874827661539987701699416841018021446826499678827570121235368306872576254306598229009326889717753996718734392718618075165049466487288359942244801903168934714614170309678757603506011866944372461588147498677098427847851318712433009748103294948229140898154267231085846307054977253156699130772999134183988575084372414985869913173854223041950981761979896495643515026760478550671129162390748164871541140497789062760779768626522387243316931878193393452785548737047784121894435472579674449705114248 061506094340065691136629320777648629750105245428304278166365832749864653836658443868224823787898586712833767298344565051523963802742101107695594850821360398938016854610915

这里是我的代码:

package picalculator; 

import java.math.BigDecimal; 
import java.math.BigInteger; 
import java.math.MathContext; 
import java.text.DateFormat; 
import java.text.SimpleDateFormat; 
import java.util.Date; 


/** 
* 
* @author ThomasSatterthwaite 
*/ 

public class PiCalculator { 

static int odd=1; 

public static void main(String[] args) { 
    System.out.println("Please wait while I calculate pi..."); 
    calculatePi(); 
    System.out.println("I have successfully calculated pi."); 
} 
public static void calculatePi() { 
    BigInteger firstFactorial; 
    BigInteger secondFactorial; 
    BigInteger firstMultiplication; 
    BigInteger firstExponent; 
    BigInteger secondExponent; 
    int firstNumber = 1103; 
    BigInteger firstAddition; 
    BigDecimal currentPi = BigDecimal.ONE; 
    BigDecimal pi = BigDecimal.ONE; 
    BigDecimal one = BigDecimal.ONE; 
    int secondNumber = 2; 
    double thirdNumber = Math.sqrt(2.0); 
    int fourthNumber = 9801; 
    BigDecimal prefix = BigDecimal.ONE; 
    DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); 

    for(int i=1;i<1000;i++){ 
     firstFactorial = factorial(4*i); 
     secondFactorial = factorial(i); 
     firstMultiplication = BigInteger.valueOf(26390*i); 
     firstExponent = exponent(secondFactorial, 4); 
     secondExponent = exponent(BigInteger.valueOf(396),4*i); 
     firstAddition = BigInteger.valueOf(firstNumber).add(firstMultiplication); 
     currentPi = currentPi.add(new BigDecimal(firstFactorial.multiply(firstAddition)).divide(new BigDecimal(firstExponent.multiply(secondExponent)), new MathContext(10000))); 
     Date date=new Date(); 
     System.out.println("Interation: " + i + " at " + dateFormat.format(date)); 
    } 

    prefix =new BigDecimal(secondNumber*thirdNumber); 
    prefix = prefix.divide(new BigDecimal(fourthNumber), new MathContext(1000)); 

    currentPi = currentPi.multiply(prefix, new MathContext(1000)); 

    pi = one.divide(currentPi, new MathContext(1000)); 

    System.out.println("Pi is: " + pi); 

    return; 
} 
public static BigInteger factorial(int a) { 

    BigInteger result=new BigInteger("1"); 
    BigInteger smallResult = new BigInteger("1"); 
    long x=a; 
    if (x==1) return smallResult; 
    while(x>1) 
    { 
     result= result.multiply(BigInteger.valueOf(x)); 

     x--; 
    } 
    return result; 
} 
public static BigInteger exponent(BigInteger a, int b) { 
    BigInteger answer=new BigInteger("1"); 

    for(int i=0;i<b;i++) { 
     answer = answer.multiply(a); 
    } 

    return answer; 
} 

} 

是任何人都能够发现与我在做什么的问题?非常感谢!

+0

你需要做的比'Math.sqrt(2.0)'更好......' – Mysticial 2012-03-20 18:59:55

+0

当你1/Math.PI会给你相同的结果时,实际执行这个公式似乎很愚蠢。 – 2012-03-20 19:04:48

+2

@Ramhound我想OP不仅仅需要'双精度'。 – Mysticial 2012-03-20 19:05:23

你应该和我= 0与currentPi =启动循环0

// ... 
BigDecimal currentPi = BigDecimal.ZERO; 
// ... 
for(int i = 0; i < 1000; i++) { 
    // ... 
} 
// ... 

这给:

3.1415926535897930237 ...

+0

它工作得很好,非常感谢你!!!!! – Toby 2012-03-20 23:52:27

+0

虽然它是精确的,但无论我在迭代中输入的数字是多少,我都会得到相同的结果,我试过了1,10,100,1000和2000,但它们都给出了相同的结果。这是预期的,还是我弄乱了一部分代码? – Toby 2012-03-21 01:37:58

+0

不,他们不给不出同样的结果,所以再次检查。但是,这个系列会很快收敛,所以您只需10次迭代就可以获得50个以上的正确小数。对于1次迭代,您有大约7个正确的小数。 – sch 2012-03-21 11:24:41

您没有正确处理第一部分总和。您开始使用i=1开始循环,初始部分金额为currentPi=1,您应该从i=0currentPi=0开始。

(这会工作,如果第一部分和(当k=0)等于1,但它实际上等于1103)

+0

它现在有效,非常感谢你! – Toby 2012-03-20 22:42:44

+0

@Toby您还应该注意有多少数字实际上是正确的。由于您使用'Math.sqrt(2.0);',我敢打赌只有前16位数字是正确的。另外,如果这个答案解决了你的问题,你应该通过点击绿色的选中标记来接受它。以前的问题也一样。 – Mysticial 2012-03-20 23:06:15

+0

哦,我没有意识到你可以这样做,谢谢! – Toby 2012-03-21 02:37:39