2012-11-03 40 views
0

這是我的第一個C作業,所以我的錯誤可能對你來說真的很明顯,如果這是我的錯誤案件。然而,這對我來說似乎很不尋常(不僅僅是工作,而且還有一些奇怪的輸出),所以我想我應該問問周圍。我試圖計算交替諧波系列的總和。這是應該做的功能(它返回一個雙精度)。循環結束提前,爲循環計數器產生負值(當i = 1; ++ i)

double series(void){ 

    double sum = 0.0; 
    int i,x; 

    for (i = 1; i > 0 ; i = i+1) 
    { 

      if (sum - (sum - 1.0/x) == 0 || sum - (sum + 1.0/x) == 0) 
      { 
        printf("To infinity and beyond... almost!\n"); 
        return sum; 
      } 
      else if (i % 2 != 0) 
      { 
        sum = sum - 1.0/x; 
      } 
      else if (i % 2 == 0) 
      { 
        sum = sum + 1.0/x; 
      } 
      else 
      { 
      printf("How did I end up here?\n"); 
      } 

    } 

    printf("I ESCAPED THE LOOP\n"); 
    return 1.0*i; 

}

當我運行程序時,它總是在最後幾行結束了(打印我躲過了LOOP行,所以for循環結束,而它應該直到運行如果滿足條件,則首先不想達到最後一行)。輸出 - 函數的返回值 - 對於i是-21473822648.000000。一個負數(實際上main中的輸出是正數,但是在那裏乘以負數-1,除去-1.0只不過是將符號改變爲不應該是的符號),當唯一改變的東西應該是在for循環介紹中爲i = 1和++ i。這是如何發生的? main所做的唯一事情就是調用函數,將double的值設置爲函數返回值的負數並打印該值。

我剛剛意識到if()語句中的操作順序可能是錯誤的,但我在其他所有內容的附加括號中修正了它。它沒有效果。

哦,這實際上不是全部問題,我實際上應該找出哪些是最佳和最差的求和命令。我只是想看看我是否可以編寫一個能夠做到的程序。任何鏈接到浮點運算相關的材料等將不勝感激。

在此先感謝任何人的建議。

+1

我會建議分配x – Nico

+2

x未初始化? –

+0

是的。是的,我只是意識到它應該是雙倍的。我把它改爲int i;雙x;在循環之前,x = 1.0 * i;在第一行的循環內部(在if-else if-chain之前)。然而,循環仍然以某種方式結束並給了我相同的結果。 – user1796924

回答

1

使用校正功能(per comments

double series(void){ 

    double sum = 0.0, x; 
    int i; 

    for (i = 1; i > 0 ; i = i+1) 
    { 
     x = 1.0*i; 
     if (sum - (sum - 1.0/x) == 0 || sum - (sum + 1.0/x) == 0) 
     { 
      printf("To infinity and beyond... almost!\n"); 
      return sum; 
     } 
     else if (i % 2 != 0) 
     { 
      sum = sum - 1.0/x; 
     } 
     else if (i % 2 == 0) 
     { 
      sum = sum + 1.0/x; 
     } 
     else 
     { 
      printf("How did I end up here?\n"); 
     } 
    } 
    printf("I ESCAPED THE LOOP\n"); 
    return 1.0*i; 
} 

,以消除使用未初始化變量的不確定的行爲,讓我們看看會發生什麼。

sum值總是-1.00.0,接近之間(模浮點舍入)-log 2(自然對數)。

iint。根據您得到的結果,我們可以推斷(並非嚴格按照邏輯來說,但無可置疑)int在您的平臺上有32位,因此i < 2^31 = 2147483648。因此,要添加或減去的術語1.0/i的量級大於2^(-31)。由於double S鍵通常有精度53位,每一個加法/減法改變sum足夠

sum - (sum - 1.0/x) == 0 || sum - (sum + 1.0/x) == 0 

從未變成真。因此循環不會以該條件結束,並且i會遞增,直至達到INT_MAX,然後再一次。

最後一個增量溢出。溢出的有符號整數會調用未定義的行爲,但在這種情況下,會發生常規的環繞行爲,並且i將包含值INT_MIN = -2147483648。然後,循環條件i > 0的計算結果爲false,循環結束時沒有從函數中獲取。

+0

哇。謝謝!我不知道(整數環繞)甚至會發生,並且對負面的我感到困惑,以至於我甚至沒有停下來想想其他可能會出錯的東西,比如if條件從來沒有發生過。我認爲這個程序會一直靜靜地運行,直到我殺死它或者即使溢出發生了。 再一次,謝謝。我想我現在至少對如何解決這些問題有一些想法。 – user1796924

+0

@ user1796924如果您將'long'替換爲'i'而不是'int',則它將運行很長時間(並且如果您的系統不使用擴展浮點表示,而只使用正常的64位IEEE754類型,將從循環內部返回)。 –

相關問題