2013-05-18 36 views
3

鑑於下列...C:傳遞浮點起作用

void test(){ 
    float a = 0.7f; 
    LOGD("Width %.1f",0.7f); 
    LOGD("Width %.1f",a); 
    fark(a); 
} 

void fark(float test){ 
    LOGD("Width %.1f",test); 
} 

此輸出....

05-18 22:35:25.215:d /自然(8241) :寬0.7

05-18 22:35:25.215:d /天然(8241):寬0.7

05-18 22:35:25.215:d /天然(8241):寬36893488147419103232.0

我對最後一個失去了什麼?

+0

這不是C問題。它在我的筆記本電腦上工作正常。也許'fark()'的聲明有點不同麼? – Elazar

+0

謝謝我會研究它 – Jackie

+0

我錯了:在我的機器中發現它也不起作用 - 我修正了定義的順序。 – Elazar

回答

12

在使用之前,您需要聲明fark

如果表示所調用的函數的表達有一個類型不包括一個原型,整數提升上每個參數進行和參數具有類型:如在章節6.5.2.2,第6段指定float被提升爲double。這些被稱爲默認參數促銷

(大膽強調加我)。

請注意,定義fark的類型與隱式假定類型不兼容會違反約束條件,並且如果調用和定義位於同一個翻譯單元中,則需要編譯器發出診斷消息。 gcc只會發出警告,但是clang拒絕代碼[error: conflicting types for 'fark']。如果調用和定義處於不同的翻譯單元中,編譯器當然不能診斷錯誤,但通過不兼容類型的表達式調用函數在任何情況下都會調用未定義的行爲。

當值0.7f轉換爲double(我使用的IEEE754 32位表示假定float,和double的IEEE754 64位的一個),將得到的

0.699999988079071 

一個值,其位-pattern(以十六進制表示)是

0x3FE6666660000000 

(偏置指數是1022,對應於-1有效指數,有效數字是1.6666660000000)。

通過 - 在堆棧或寄存器 - 到fark

fark從該表示中讀取32位 - 因爲它根據其定義預計float - 取決於double是如何通過的,它可以讀取高階32位或低階32。

它沒有在這種情況下讀出的低階32位,導致了float值與位模式

0x60000000 

其具有0xC0 = 192一個偏置指數,對應於偏指數192 - 127 = 65和有效數1.000000。換言之,即是

2^65 = 36893488147419103232 

float表示其上打印的值。

+0

加1 ..哇。 – Elazar