關於這段C代碼為什麼會輸出這種結果?

#include &
int main(void)
{
union
{
double d;
float f;
} u;
u.d = 10.0;
printf("%f
",u.d);
u.f = 10.0;
printf("%f
",u.d);
return 0;
}

gcc編譯未報錯,沒有警告.

運行結果是:

10.000000
10.000002

後面這個2是怎麼來的


改一下程序:

#include &
#include &
#include &

int main(void)
{
union
{
double d;
float f;
uint64_t u;
} u;

u.d = 10.0;
printf("%.23f
", u.d);
printf("0x%016" PRIX64 "

", u.u);

u.f = 10.0;
printf("%.23f
", u.d);
printf("0x%016" PRIX64 "

", u.u);

u.u = 0;
u.f = 10.0;
printf("%.23f
", u.d);
printf("0x%016" PRIX64 "

", u.u);
}

輸出:

10.00000000000000000000000
0x4024000000000000

10.00000194087624549865723
0x4024000041200000

0.00000000000000000000000
0x0000000041200000

可以看到,在小端位元組序的情況下,u.f = 10 寫進了 u 的低32位(其單精度浮點數的二進位表示為0x41200000),所以類型雙關(type punning)後令u.d 的尾數大了一點,具體來說是大了412_{16} 	imes 2^{-29}=1.9408762454986572265625 	imes 10^{-6}


回去複習什麼叫union -&>_-&>


不請自來。IEEE754是編譯器浮點數標準。

float和double的不同在於bit寬度和表示範圍。這個差距大概是四捨五入出來的。具體算下即可。


看一下CSAPP 2.4.2浮點表示 3.9.3 聯合體,你就明白了


推薦閱讀:

開發一個 C++ 編譯器的難度有多大,難點又在哪裡?
量子計算機的出現能否加快cpp的編譯時間?
為什麼給Mac編寫的軟體不能在Windows上運行?
Haskell 執行速度怎樣?
通用中間語言 (CIL) 怎麼學習?

TAG:程序員 | 編程 | C編程語言 | 編譯 |