2012-03-20 84 views
1

我正在實施這一算法:實施算法來計算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

回答

2

你應該和我= 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

4

您沒有正確處理第一部分總和。您開始使用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