2011-04-22 30 views
1

我已經開始學習c語言,但問題是我對如何使用浮點數字感到困惑。我使用Xcode作爲IDE。以下是這讓我結果弄得:c中的浮點數[Xcode IDE]

float x1 = 1.123456789123456789f; 
double x2 = 1.123456789123456789f; 
float x3 = 987654321.123456789f; 
double x4 = 987654321.123456789f; 

printf("x1 = %.20f\n", x1); 
printf("x2 = %.20f\n", x2); 
printf("x3 = %10.10f\n", x3); 
printf("x4 = %10.10f\n", x4); 

輸出是:

 
x1 = 1.12345683574676513672 
x2 = 1.12345683574676513672 
x3 = 987654336.0000000000 
x4 = 987654336.0000000000 

的問題是,爲什麼x1x2失去了浮動的數字1.12345678後?爲什麼和x4被截斷?

+0

此外,x3和x4會產生錯誤的十進制數 - 987654336而不是987654321 – Centurion 2011-04-22 11:32:50

回答

4

這裏的基本問題是,floating point numbers只具有有限的精度:它們只能在空間不足之前表示許多有效數字。它確實是而不是問題如果這些數字在小數點之前或之後,則有效數字的總數很重要。請注意,這個問題是而不是限於C,它可以在使用浮點數的所有語言/環境中看到。

double應該能夠存儲大約兩倍於float的位數,但所有的浮點文字都是float文字。刪除double行中的f後綴以實際使用double的所有可用位。

+0

非常感謝。我在文檔中讀到float類型的精度是6,double是15.但我不明白這是什麼意思。最後,我認爲精度意味着允許的最大相鄰位數。外面的所有東西都被截斷或神奇地轉換成其他數字:)再次感謝您。 – Centurion 2011-04-22 11:44:21

+0

「神奇的轉換」發生是因爲IEEE浮點數實際存儲二進制數字(它被截斷)。將二進制數轉換爲十進制並不總是精確的,所以你會得到「奇怪的數字」而不是確切的數字。換句話說:如果你看看你的輸入和輸出的二進制表示,你會看到它們被「乾淨地截斷」。 – 2011-04-22 11:46:01

1

你缺少的是你將每個數字通過2個鹼基轉換,而x2和x4也通過擴展類型轉換。

首先你十進制文字的,其中編譯器轉換爲float類型的二進制小數,其具有23二進制數位(相當於約7.2十進制數字)精度和不能準確地代表最小數,即使是那些適合他們的精確度。然後將x2和x4分配給double變量,但由於所有不符合23位二進制數字的東西都已經被裁剪,所以它們不會奇蹟般地重新獲得文字中存在的精度。

然後,您通過printf將二進制分數轉換回十進制數,並獲得前面提到的ca. 7.2十進制數字是正確的,並且之後的所有內容都反映了由基本轉換創建的表示舍入錯誤。

它基本上是一樣的,如果你試圖將1/3轉換成小數部分0.333並回到適當的分數333/1000 - 嘿,爲什麼不是1/3?

閱讀the floating-point guide瞭解更多信息。

+0

謝謝,非常有用的鏈接。 – Centurion 2011-04-22 12:08:38

+0

此外,有什麼解決方法的貨幣格式(12.23 $,145789.45)四捨五入錯誤是不可接受的? – Centurion 2011-04-22 12:16:52

+0

@ 4centimeter:對於那些你使用定點數而不是浮點數的人。例如,在Java中,可能是一個BigDecimal,可能有庫在C中執行相同操作。或者,您以美分(或您需要的最小可能單位)存儲貨幣金額並將其格式化爲正確工作。 – 2011-04-22 12:34:41