2012-09-23 143 views
3

在這個程序中,我編寫了幾個公式和一個公式,但我得到的結果並不一致,儘管每次運行都是相同的代碼和輸入。有問題的功能是「WqFormula」。在一些運行中,我得到了正確的結果是0.041667,而在其他運行中,我得到了0.000000。我正在使用GCC 4.6.3在Ubuntu(64位)上進行編譯。另一件事是我試着編譯並使用GCC 4.4.6在電腦上運行它,它給了我每一個公式完全不同的結果。繼承人的代碼:結果不一致(C)?

float PoFormula(float, float, int); 
float LFormula(float, float, int); 
float WFormula(float, float, int); 
float LqFormula(float, float, int); 
float WqFormula(float, float, int); 


int main() 
{ 
    int n, m; //# of arrivals, # of service channels 
    float mu, lambda; //avg serviced, arrivals in time period 
    printf("lambda (l) = "); 
    scanf ("%f", &lambda); 
    printf("mu (m) = "); 
    scanf ("%f", &mu); 
    printf("m (M) = "); 
    scanf("%i", &m); 
    float test, test2, test3, test4, test5; 
    test = PoFormula(lambda, mu, m); 
    printf("PoFormula is %f\n", test); 
    test2 = LFormula(lambda, mu, m); 
    printf("LFormula is %f\n", test2); 
    test3 = WFormula(lambda, mu, m); 
    printf("WFormula is %f\n", test3); 
    test4 = LqFormula(lambda, mu, m); 
    printf("LqFormula is %f\n", test4); 
    test5 = WqFormula(lambda, mu, m); 
    printf("WqFormula is %f\n", test5); 
    return; 
} 

float PoFormula(float lambda, float mu, int m) 
{ 
    float summation, factorial = 1; 
    int i, j; 
    for (i=0; i < (m); i++) 
    { 
     for (j=1; j < (i+1); j++) factorial *= j; 
     factorial = 1/factorial; 
     factorial = factorial * pow ((lambda/mu), i); 
     summation += factorial; 
    } 
    factorial = 1; 
    for (j=1; j < (m+1); j++) factorial *= j; 
    factorial = 1/factorial; 
    factorial = factorial * pow ((lambda/mu), m); 
    factorial = factorial * ((m*mu)/((m*mu) - lambda)); 
    factorial += summation; 
    factorial = 1/factorial; 
    return factorial; 
} 

float LFormula(float lambda, float mu, int m) 
{ 
    float factorial = 1, po; 
    int j; 
    po = PoFormula(lambda, mu, m); 
    for (j=1; j < (m); j++) factorial *= j; 
    factorial *= pow(((m*mu) - lambda), 2); 
    factorial = (((lambda*mu)*(pow((lambda/mu),m)))/factorial) * po; 
    factorial += (lambda/mu); 
    return factorial; 
} 

float WFormula(float lambda, float mu, int m) 
{ 
    float factorial = LFormula(lambda, mu, m); 
    factorial /= lambda; 
    return factorial; 
} 

float LqFormula(float lambda, float mu, int m) 
{ 
    float factorial = LFormula(lambda, mu, m); 
    factorial -= (lambda/mu); 
    return factorial; 
} 

float WqFormula(float lambda, float mu, int m) 
{ 
    float factorial = LqFormula(lambda, mu, m); 
    factorial /= lambda; 
    return factorial; 
} 

應該怎樣打印每次是這樣的:

PoFormula是0.500000

LFormula是0.750000

WFormula是0.375000

LqFormula是0.083333

WqFormula是0.041667

如果需要,我很樂意提供更多信息。

+1

您測試哪些特定輸入? – DCoder

+0

它是用雙而不是浮動做到這一點嗎?它可能與精度有關嗎? – Sqeaky

+0

知道我忘記了東西,輸入分別是2,3,2。我沒有嘗試過使用雙打,教授推薦漂浮物來達到精確的目的。 – boutrosc

回答

3

以下函數使用summation,而不對其進行初始化:

float PoFormula(float lambda, float mu, int m) 
{ 
    float summation, factorial = 1; 
    for (i=0; i < (m); i++) 
    { 
    // .... 
    summation += factorial; 
    } 

所以你不能指望這個功能的任何結果纔有意義。

你的編譯器可以警告你這樣的問題,如果你要求它(和你真的應該!):

對於GCC,與-Wall -Wextra編譯(個人而言,我也用-pedantic,情況因人而異),以獲得儘可能儘可能多的警告。但是,在這種特殊情況下,GCC似乎對這個問題一無所知,直到您使用-Oenable optimization

您可以立即停止閱讀,只需在編譯時使用-Wall -Wextra -O即可解決此問題。


GCC的未初始化的變量分析,有兩種不同的檢查 - 「絕對使用未初始化」和「可能使用未初始化」。分析作品不同,這取決於優化是否啓用:

  • 如果優化是關閉(-O0,默認值),編譯器進行一次分析同時通過檢查。
  • 如果優化處於打開狀態,編譯器會執行兩遍 - 第一遍只執行「絕對未初始化」檢查,第二遍執行優化後(因爲優化可能會改變控制流)並執行兩個檢查。

我沒有與海合會內部足夠的熟悉,看看會發生什麼藏在你的代碼這個問題,但我把它降低到this test case,如果有人想進行深入分析。如果展開循環,即使沒有-O也會得到警告,因此循環展開優化可能與它有關。


如果使用MSVC,編譯/W4獲得最大的警告。 MSVC將此未初始化的變量報告爲默認警告級別的問題,無論是否使用優化。

+0

非常感謝!這將有助於解決未來的問題。 – boutrosc