2014-10-09 208 views
0

所以我的代碼使用for和while循環和遞歸方法打印出Pi的估計值。這是所有工作,除了我的編譯器說我的遞歸方法中的if語句有堆棧溢出錯誤。堆棧溢出錯誤(Java)

public static final double REAL_PI = 3.14159;//PI is the value Mr.B gave us on the handout 
public static double Pi = 0; //Pi is the value of Pi that this program calculates 
public static int m = 0; 
public static int c = 0; 


public static void main (String [] args) 
{ 
    Algorithm(); //calls on method of calculating pi 
    System.out.println("Calculated pi: " + Pi); //prints out pi 
    countDigits(Pi); //calls on countdigits method 
    System.out.println("Number of digits: " + c); //has the computer print out the count because that's how many digits are the same 
    While(); 
    Recursive(1, 0.0); //calls on estimate digits method 
} 

public static double Algorithm() //should return a double (pi) 
{ 
    for(m=1; m<=100000; m++) 
    { 
     Pi += 4*(Math.pow(-1, m-1)/((2*m)-1));//Math.pow uses math package to calculate a power to use the algorithm 
    } 
    return Pi; 
} 

public static int countDigits (double Pi) 
{ 
    int a = (int) Pi; //the int cast makes Pi and REAL_PI into integers so the program can compare each digit separately 
    int b = (int) REAL_PI; 
    int c = 0; 
    int count = 0; 
    while(a == b)//if m less then or equal to 100,000 then while loop runs 
    { 
     count ++; 
     a = (int) (Pi*(Math.pow(10,count))); //if a=b then the computer will multiply Pi and REAL_PI by 10 
     b = (int) (REAL_PI*(Math.pow(10,count))); 
     /*when you input a and b 
     * while loop compares them 
     * if a = b then loop continues until a doesn't equal b and loop ends 
     */ 
    } 
    c = count; //gives c the value of the count so it can be used outside the method 
    return count; 
} 
public static double While() 
{ 
    int m = 1; 
    Pi = 0.0; 
    while (countDigits(Pi) < 6) 
    { 
     Pi += 4*(Math.pow(-1, m-1)/((2*m)-1)); 
     m++; 
    } 
    Pi = (int)(Pi * 1000000); 
    Pi = (double)(Pi/1000000); 
    System.out.println("Pi using while loop: " + Pi); 
    return Pi; 
} 

public static double Recursive(int m,double Pi) 
{ 
    Pi += 4*(Math.pow(-1, m-1)/((2*m)-1)); 
    if (countDigits(Pi) < 6) 
    { 
     return Pi += Recursive(m+1,Pi); 
    } 
    Pi = (int)(Pi * 1000000); 
    Pi = (double)(Pi/1000000); 
    System.out.println("Pi using recursive: " + Pi); 
    return Pi; 
} 

}

+0

當達到此限制時,只能在堆棧中進行如此多的方法調用,程序將通過一個運行時錯誤而不是編譯器錯誤的stackoverflow錯誤。 – brso05 2014-10-09 19:47:48

+1

您可能想嘗試計算pi的更少位數...... – brso05 2014-10-09 19:48:32

+0

另外'c = count;'不能在方法外部使用它,因爲還有一個局部變量'c'。 – MrHug 2014-10-09 19:51:24

回答

5

的問題是,萊布尼茲系列計算π收斂EXTREMELY慢。使用程序中,我發現,經過3663次迭代(當我殺了程序),該值是這樣的:

pi=3.141865802997432 
pi=3.1413195787723875 
pi=3.1418656538577117 
pi=3.1413197278306884 

不過只有3位小數,並且它會甚至需要很長的時間是準確的到4.堆棧不夠大,無法存放這麼多的遞歸調用,最終會溢出。