2012-06-22 264 views
1

使用printf與%d作爲格式說明符並給出float作爲參數,例如2.345,它會打印1546188227.所以,我明白這可能是由於單點浮點精度格式轉換爲簡單的小數格式。但是當我們用%d打印2.000作爲格式說明符時,爲什麼只打印0? 請幫忙。關於printf輸出困惑

+1

發佈實際數據來源。看起來你的代碼可能會在'printf'中混淆參數。另外,請注意'%d'用於打印整數; '%f'就是你想要的花車。 – dirkgently

回答

4

格式說明符%d只能與int(和兼容類型)的值一起使用。試圖使用%dfloat或任何其他類型產生未定義的行爲。這是這裏真正適用的唯一解釋。從語言的角度來看,你看到的輸出基本上是隨機的。而且你不能保證得到任何輸出。

如果您仍然有興趣研究您看到的輸出的具體原因(無論它有多少意義),您必須執行特定於平臺的調查,因爲實際行爲嚴重取決於各種實施細節。你甚至沒有在你的帖子中提到你的平臺。

無論如何,作爲附註,請注意不可能將float值作爲可變參數傳遞給可變參數函數。 float在這種情況下的值總是被轉換爲double並作爲double傳遞。所以在你的情況下,你試圖打印的值是double。行爲仍然未定義。

+0

但是,雖然未定義的行爲,它解釋了輸出。 「double」2.345的尾數的低32位是「0x5c28f5c3 = 1546188227」,而「double」2.0的尾數的低32位都是0.因此'printf'只是解釋'double'作爲'int',並且平臺是小端的,所以四個字節是尾數的低32位。 –

0

如果你想使打印整數值,投彩車以整數呼叫:

printf("ints: %d %d", (int) 2.345, (int) 2.000); 

否則,使用浮點格式標識符:

printf("floats: %f %f", 2.345, 2.000); 
0

當你使用帶有錯誤格式說明符的printf作爲相應的參數,結果是未定義的行爲。它可能是任何事物,並且可能因實施而異。只有正確使用指定的格式才能定義行爲。

0

首先是一個小的挑剔:實際上,2.345實際上是double類型的,而不是float類型的,此外,甚至像float 2.345f這樣的float類型也會被轉換爲double類型作爲函數的參數需要可變數量的參數,如printf。

但是,這裏發生的是double值的(通常)64位被髮送到printf,然後它將(通常)32位這些位解釋爲整數值。所以恰好那些位是零。

根據標準,這就是所謂的未定義行爲:編譯器被允許做任何事情。

1

here,輸入2.345,點擊「四捨五入」。觀察64位十六進制值:4002C28F5C28F5C3。請注意0​​是0x5c28f5c3

現在重複2.00。觀察64位十六進制值是4000000000000000

P.S.當你說你提供了一個float的論點時,你顯然意味着你給出了一個double的論點。

1

這裏什麼ISO/IEC 9899:1999標準7.19美元。6州:

If a conversion specification is invalid, the behavior is undefined.239) 
If any argument is not the correct type for the corresponding conversion 
specification, the behavior is undefined.