2012-04-09 47 views
-1

可能重複:
strange output in comparision of float with float literal簡單的C程序處理小數

所以計劃只是讀取一串數字,並通過總數除以發現的,平均進入。然而,最後的結果在最後加上了幾個小數,我不確定它爲什麼這樣做。

對於此給定的輸入: 483,10,3051,188,200,0

輸出應該786.4 而是它是786.400024。我究竟做錯了什麼?先謝謝你。

int main(int argc, char** argv) 
{ 
    int averageOfNumbers = 0; 

    printf("Enter the sequence of numbers:"); 
    int nextNumber; 
    float numberCounter = 0; 
    do 
    { 
      scanf("%d", &nextNumber); 
      if(nextNumber > 0) 
      { 
        numberCounter++; 
        averageOfNumbers += nextNumber; 
      } 
    } 
    while(nextNumber > 0); 
    float finalAverage = (float) (averageOfNumbers/numberCounter); 
    averageOfNumbers = averageOfNumbers/numberCounter; 
    printf("Average of the numbers in the sequence is %f\n", finalAverage); 

}

+0

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – Mysticial 2012-04-09 07:10:04

+0

作業?如果是這樣,請標記爲這樣。 – 2012-04-09 07:10:26

+1

您可以截斷結果以隱藏不精確性,如'printf(「%。2f」,finalAverage);'ref:printf manual(http://www.manpagez.com/man/3/printf/) – hellork 2012-04-09 07:20:21

回答

3

浮點數實數提供精確的,但不精確的近似。 (如何精確取決於它們的大小:精度多少位是在你使用的浮點類型可用。)

IEEE 754浮點(多臺計算機上用了一個很流行的代表)使用二進制。這意味着諸如1/2,1/4,1/8及其組合的二進制分數:3/8,5/16等被精確地表示(在可用的精度的多少位的範圍內)。不基於兩個冪的分數不能完全表示。

數量的1/10或0.1沒有準確表示。當您在機器中輸入0.1時,它會被轉換爲一個值接近0.1的許多二進制數字。當你用printf或你有什麼打印回來時,你會再次得到0.1,因爲printf函數將其捨去,所以它看起來像0.1正在被精確表示:0.1進入機器,並且由golly,0.1出來。假設精確度爲10個十進制數字來查看0.1和實際值之間的差異,但您只打印到8位數字。那麼,它當然會顯示爲0.1。你的浮點打印程序已經切斷了錯誤!

C printf中的%f轉換說明符將使用更多數字用於較大數字,因爲它使用小數點後的固定位數,默認值爲6。因此,例如0.002將打印爲0.002000。但數字123456將打印爲123456.000000。數量越大,印刷的數字越高。當用%f打印786.4時,實際上是要求9位十進制數字的精度。三爲786整數部分,然後六個以上。

您正在使用float,這很可能是32位IEEE 754浮點數。這隻有24位的精度。 (1位用於符號,7位用於二進制指數,從24開始)。24位相當於精確度只有7位十進制數!

因此,您要求機器從浮點表示法中打印出786.4(對此它有不精確的表示形式,請記住!),以浮點表示形式表示,該表示法僅適用於約7位十進制有效數字。你要求兩個不在那裏的精度數字,因此得到兩個錯誤數字。

所以你可以做的是使用一個更寬的類型像double和/或改變你打印結果的方式。不要問這麼多有意義的人物。例如,嘗試%.3f(小數點後三位數字)。

float型用C應該很少的方式來使用。您通常希望使用double類型。 float有其用途,例如節省大型陣列的空間。

0

使用雙能解決你的問題。漂浮的準確性和精確性是問題的原因。

+2

使用雙重簡單地將問題進一步在地毯下掃描。如果您將該值顯示爲雙倍以下的重要數字,則您將再次顯示結果沒有雙重確切表示的事實。 – Kaz 2012-04-09 07:34:11

0

浮點類型不能代表完全準確的所有號碼 - 許多數字永遠只能大致與浮點表示;這意味着給定足夠的有效數字,你最終會看到這些數字的精度損失,這些數字不能很好地適應表示。

使用float數據類型的問題在於它是浮點類型中準確度最低的。 (C和C++的默認浮點類型爲 - 這是你應該使用一個,你應該避免使用浮動除非你有一些令人信服的理由,否則使用它)。在一個現代的32位桌面平臺,浮動只能精確到6-7顯著數字對於一些近似數,在同一個平臺上可以精確到13-14 SF相同數目(注意:這是有效數字和不是小數點!)。

我強烈建議你花時間點數如何浮動工作讀了(其輸入到谷歌,你會發現解釋的負荷!);瞭解他們如何在內部代表將有助於使你成爲一個更好的程序員

+0

瞭解浮點數將使您成爲更好的數字分析師。如果你想成爲一個更好的程序員,在你的餘生中發誓使用浮點數。最近我最近看到了Gerald Sussman最近在infoq上的一次演講,他承認,只要代碼中存在浮點數,他就會感到害怕。哇,我的想法正好。 :) – Kaz 2012-04-09 18:26:02

+1

談話在這裏:http://www.infoq.com/presentations/We-Really-Dont-Know-How-To-Compute。評論從0:11:00左右開始。他說:「......浮動的東西是危險的」*和*「沒有什麼比浮點數更讓我的內心產生恐懼」*和*「數值分析:我知道的最大的黑色藝術」*。大聲笑!乾杯。 – Kaz 2012-04-09 18:26:57