2012-10-07 21 views
0

所以我試圖做這樣的問題:如何近似E在無窮級數用C

Problem

不過,我不完全知道從哪裏開始或究竟是什麼我期待的。另外,我被告知我應該給予程序輸入例如:零(0),很小(0.00001),而不是很小(0.1)。

我被給了這個:http://en.wikipedia.org/wiki/E_%28mathematical_constant%29作爲參考,但該公式看起來不像問題中的那個。

最後,我被告知該程序的輸入是一個小數字Epsilon。例如,您可以假設0.00001f。

您繼續添加無限序列,直到當前項的值低於Epsilon。

但總而言之,我不知道這意味着什麼。我有點理解wiki上的等式。但是,我不知道從哪裏開始解決問題。看看它,沒有人知道我應該在C中使用什麼樣的公式,什麼是「E」以及它在哪裏出現(即在公式中,我理解它假設是用戶輸入)。

到目前爲止的代碼

#include <stdio.h> 
#include <math.h> 

//Program that takes in multiple dates and determines the earliest one 
int main(void) 
{ 
    float e = 0; 
    float s = 0; 
    float ct = 1; 
    float ot= 1; 
    int n = 0; 
    float i = 0; 
    float den = 0; 
    int count = 0; 

    printf("Enter a value for E: "); 
    scanf("%f", &e); 

    printf("The value of e is: %f", e); 


    for(n = 0; ct > e; n++) 
    { 
     count++; 
      printf("The value of the current term is: %f", ct); 

     printf("In here %d\n", count); 

     den = 0; 

     for(i = n; i > 0; i--) 
     { 
      den *= i; 
     } 

     //If the old term is one (meaning the very first term), then just set that to the current term 
     if (ot= 1) 
     { 
      ct = ot - (1.0/den); 
     } 
     //If n is even, add the term as per the rules of the formula 
     else if (n%2 == 0) 
     { 
      ct = ot + (1.0/den); 
      ot = ct; 
     } 
     //Else if n is odd, subtract the term as per the rules of the formula 
     else 
     { 
      ct = ot - (1.0/den); 
      ot = ct; 
     } 

     //If the current term becomes less than epsilon (the user input), printout the value and break from the loop 
     if (ct < epsilon) 
     { 
      printf("%f is less than %f",ct ,e); 
      break; 
     } 
    } 

    return 0; 
} 

電流輸出

Enter a value for E: .00001 
The value of e is: 0.000010 
The value of the current term is: 1.000000 
In here 1 
-1.#INF00 is less than 0.000010 

所以根據大家的意見,並使用來自維基百科第四屆「紊亂」方程就像有人告訴我,這是我提出的代碼。我腦海中的邏輯似乎與每個人一直在說的一致。但是輸出完全不是我想要實現的。有沒有人有任何想法看這段代碼我可能做錯了什麼?

+1

有很多方法可以近似估計e的值,維基百科的文章也包含了所示的近似值:http://en.wikipedia.org/wiki/E_%28mathematical_constant%29#Alternative_characterizations第四個等式。至於你的問題,只需計算分解並反轉即可。當分解的反轉小於閾值(ε - 您可以將其定義爲1e-5f或1e-6)時,您可以停止。 – nhahtdh

+1

這是一個很好的參考:[常數e及其計算](http://numbers.computation.free.fr/Constants/E/e.html)(來自[數學常量和計算](http://數字。 computation.free.fr/Constants/constants.html))。 – deltheil

+0

@nhahtdh只是爲了確定,你的意思是來自wiki的第4個「排列紊亂」方程,對嗎? –

回答

2

Σ代表總和,所以你的方程意味着計算開始在n = 0的項的總和與向無窮打算:

enter image description here

記號n!指「階乘」,其是數字的一個至n的產物:

enter image description here

更準確地計算每次迭代代表實際值。 ε是一個誤差項,表示迭代的變化小於ε量。

開始計算你需要一些條件開始的互爲作用:

unsigned int n = 0; // Iteration. Start with n=0; 
double fact = 1; // 0! = 1. Keep running product of iteration numbers for factorial. 
double sum = 0;  // Starting summation. Keep a running sum of terms. 
double last;  // Sum of previous iteration for computing e 
double e;   // epsilon value for deciding when done. 

則算法很簡單:

  1. 商店前面的總和。
  2. 計算下一筆總和。
  3. 更新n和計算下一個因子。
  4. 檢查是否在新主場迎戰老迭代差超過小量。

的代碼:

do { 
    last = sum; 
    sum += 1/fact; 
    fact *= ++n; 
} while(sum-last >= e); 
+0

非常感謝。當然,這個方程似乎更清晰得多,並且這樣解釋! :) –

+0

我唯一的問題是,如果你設置了'e = 0',你怎麼才能真正顯示哪個術語最終變成了小於0?因爲測試它,它最終讀取「0.000000小於0.000000」,但實際上並未指定值。在小數位方面,C不可能實現那麼遠嗎? –

+0

'e = 0'意味着術語之間沒有變化。由於'sum-last> = e'將始終爲真,除非e爲負值,則應該將其改爲'sum-last> e'。然後它應該停止。要打印更多小數位,請嘗試使用'%.15lf'作爲格式說明符(小數點後15位)或'%g'(科學記數法)。 –

1

這個求和符號給你一個線索:你需要一個循環。

什麼是0!? 1,當然。所以你的e的初始值是1.

接下來,你將爲n寫入一個從1到更大值的循環(無窮大可能表示一個while循環),在這裏你計算每個連續項,看看它的大小是否超過了你的epsilon ,並將其添加到e的總和中。

當您的條款小於您的epsilon時,請停止循環。

現在不用擔心用戶輸入。讓你的功能工作。硬編碼一個epsilon,看看你改變它會發生什麼。保留最後一位的輸入。

您需要一個很好的因子函數。 (不正確 - 感謝Mat提醒我。)

你問過常數e從哪裏來?和系列?該系列是指數函數的泰勒級數展開式。查看任何介紹微積分文本。常數e很簡單,指數函數指數爲1.

我已經有了一個很好的Java版本在這裏工作,但是我不會發布它。它看起來就像C函數一樣,所以我不想放棄它。

更新:既然你已經證明你的,我會告訴你我:

package cruft; 

/** 
* MathConstant uses infinite series to calculate constants (e.g. Euler) 
* @author Michael 
* @link 
* @since 10/7/12 12:24 PM 
*/ 
public class MathConstant { 

    public static void main(String[] args) { 
     double epsilon = 1.0e-25; 
     System.out.println(String.format("e = %40.35f", e(epsilon))); 
    } 

    // value should be 2.71828182845904523536028747135266249775724709369995 
    //   e = 2.718281828459045 
    public static double e(double epsilon) { 
     double euler = 1.0; 
     double term = 1.0; 
     int n = 1; 
     while (term > epsilon) { 
      term /= n++; 
      euler += term; 
     } 
     return euler; 
    } 
} 

但是,如果你需要一個階乘函數我建議表,記憶化,並通過伽瑪功能天真的學生實施。谷歌對於那些如果你不知道這些是什麼。祝你好運。

+5

根本不需要因子函數。只需在循環中計算它,保存最後一個值。 – Mat

+1

雖然不需要真正的階乘函數,但我們可以先讓它工作,然後再快速完成。也可以用因子函數來思考。 – nhahtdh

+1

絕對如此,墊子。我會修改我的答案。 – duffymo

1

你需要寫一個開始C程序。網絡上有很多來源,包括如何從argc和argv變量獲取用戶輸入。它看起來像是如果沒有輸入,則爲epsilon使用0.00001f。 (請使用獲得該程序試圖讓它接受輸入之前的工作)

爲了計算系列中,將使用一個循環和一些變量:總和,current_term,和n。在每次循環迭代中,使用n,增量n來計算current_term,檢查當前項是否小於ε,並且如果不是將current_term添加到總和中。

大的陷阱,以避免在這裏被錯誤計算整數除法。例如,您將希望避免像1/n這樣的表達式。如果你打算使用這樣的表達式,請改爲使用1.0/n。

+0

我根據你寫的內容更新了OP。 –

1

那麼其實這個方案是非常類似於Deitel公司在學習給計劃在C中的,現在好了,以點(誤差不能爲0原因e是一個無理數,因此它不能準確計算)我在這裏有一個可能對你非常有用的代碼。

#include <stdio.h> 


/* Function Prototypes*/ 
long double eulerCalculator(float error, signed long int *iterations); 
signed long int factorial(int j); 


/* The main body of the program */ 
int main(void) 
{ 
    /*Variable declaration*/ 
    float error; 
    signed long int iterations = 1; 

    printf("Max Epsilon admited: "); 
    scanf("%f", &error); 
    printf("\n The Euler calculated is: %f\n", eulerCalculator(error, &iterations)); 
    printf("\n The last calculated fraction is: %f\n", factorial(iterations)); 
    return 1; 
} 


long double eulerCalculator(float error, signed long int *iterations) 
{ 
    /* We declare the variables*/ 
    long double n, ecalc; 


    /* We initialize result and e constant*/ 
    ecalc = 1; 

    /* While the error is higher than than the calcualted different keep the loop */ 
    do { 

     n = ((long double) (1.0/factorial(*iterations))); 
     ecalc += n; 
     ++*iterations; 

    } while (error < n); 


    return ecalc; 
} 

signed long int factorial(signed long int j) 
{ 
    signed long int b = j - 1; 

    for (; b > 1; b--){ 
     j *= b; 
    } 

    return j; 
} 
1

寫MAIN函數和函數來計算下面系列的大致總和。

  (n!)/(2n+1)! (from n=1 to infinity) 

內的主功能:

  • 從 標準輸入讀取類型DOUBLE(期望的精確度)的可變EPSILON。 EPSILON是一個非常小的正數,小於或等於 到10 ^( - 6)。
  • EPSILON值將作爲參數傳遞給FUNCTION。

中的函數:

  • 在do-while循環:
    • 繼續添加了條款,直到|錫+ 1 - 錫| < EPSILON。
    • Sn是前n個項的總和。
    • Sn + 1是第一(n + 1)項之和。 當達到期望的精度EPSILON時,打印總和和條款號碼 添加到總和。

TEST與不同EPSILON值程序(從10 ^( - 6)至10 ^( - 12)) 一次一個。