行爲

2015-09-19 15 views
4
#include<stdio.h> 
int main() 
{ 
    float f = 0.1; 
    double d = 0.1; 
    printf("%lu %lu %lu %lu\n", sizeof(f), sizeof(0.1f), sizeof(0.1), sizeof(d)); 
    return 0; 
} 

輸出行爲

$ ./a.out 
4 4 8 8 

按照上面的代碼中,我們可以看到sizeof(0.1)sizeof(0.1f)不相同。 sizeof(0.1) is 8 bytes,而sizeof(0.1f) is 4 bytes。 ,但在分配value to float variable f時,會自動將其大小截斷爲4 bytes

儘管在下面的代碼,而與浮比較它X它不截斷和4 bytes of float8 bytes of 0.1相比,具有0.1f作爲兩者的float x匹配值是4個字節。

#include<stdio.h> 
int main() 
{ 
    float x = 0.1; 
    if (x == 0.1) 
     printf("IF"); 
    else if (x == 0.1f) 
     printf("ELSE IF"); 
    else 
     printf("ELSE"); 
} 

輸出

$ ./a.out 
ELSE IF 

爲什麼和如何分配時,而不是在比較它截斷?

+2

'float'類型是[*單精度*浮點類型](https://en.wikipedia.org/wiki/Single-precision_floating-point_format),而'double'是一個* double precision * floating點類型。我還建議你閱讀[「是浮點數學打破?」](http://stackoverflow.com/questions/588004/is-floating-point-math-broken),它會幫助你理解爲什麼'0.1f! = 0.1'。 –

+0

有什麼辦法解決四捨五入的問題嗎? –

+1

@NitinTripathi永遠不要比較浮點數是否相等,並期望它們總是少量關閉。除非絕對必要,否則您也可以避免使用「float」類型。 – fuz

回答

8

沒有後綴的浮點數文字是double。用f作爲後綴使float類型的文字成爲可能。

當分配給變量時,右操作數=被轉換爲左操作數的類型,因此您觀察到截斷。

比較時,將操作數==被轉換成兩個操作數的大,所以x == 0.1就像(double)x == 0.1,其是假,因爲(double)(float)0.1不是0.1由於四捨五入問題相等。在x == 0.1f中,兩個操作數的類型爲float,這會導致您的計算機上的值相等。

浮點數學很棘手,請閱讀標準以瞭解更多細節。

+0

謝謝@FUZxxl,這真的很有幫助 無論你在第三段說什麼,我實際上試圖實現它,發現如下: 'printf(「%lu%lu%lu%lu \ n」,sizeof((double)f),sizeof((double)0.1 (double)0.1),sizeof((double)d)); printf(「%15.15f%15.15f%15.15f%15.15f \ n」,(double)f,(double)0.1f ,(雙)0.1,(雙)d);' **輸出:** '$ ./a.out 0.100000001490116 0.100000001490116 0.100000000000000 0.100000000000000' 我如果我們看到,所有四個都通過類型轉換轉換爲8個字節,但是在從float類型轉換爲double類型時發生舍入問題。 –

+1

@NitinTripathi你的評論出了什麼問題,'sizeof((double)x)'總是會輸出'8',不管'x'是什麼 –

+0

感謝@ M.M指出。 (sizeof((double)f),sizeof((double)0.1f),sizeof((double)0.1),sizeof((double) )d)); printf(「%15.15f%15.15f%15.15f%15.15f \ n」,(double)f,(double)0.1f,(double)0.1,(double)d);'Output:'$ ./a。 out 8 8 8 8 0.100000001490116 0.100000001490116 0.100000000000000 0.100000000000000'如果我們看到,所有四個都通過類型轉換轉換爲8個字節,但是當從float類型轉換爲double類型時會發生舍入問題。 –

2

0.1f(數字後面的「f」)是計算機的浮點數,那麼您的compailer知道他需要將它存儲爲float而不是double。 所以浮動0.1不等於0.1,其等於0.1F

2

除非指定爲浮動狀0.1f0.1浮點常數是雙。行

float f = 0.1;

裝置創建一個雙用值0.1和投它漂浮並在過程中失去精度。行

float x = 0.1; 
if (x == 0.1) 

將導致x隱式轉換爲double,但它將具有與例如稍微不同的值。 double x = 0.1;

1

當您編寫0.1時,默認爲double。後綴f明確地使其浮動。

第二個問題float被存儲爲ieee標準所以它在else if中進行,因爲0.1f等價轉換爲double是不相同的。

https://en.wikipedia.org/wiki/Floating_point

1

0.1是雙值而0.1f是浮點值。 我們可以編寫float x=0.1以及double x=0.1的原因是由於隱式轉換。

但是通過使用後綴f你可以使它成爲一個浮點類型。

在這 -

if(x == 0.1) 

是FLASE因爲0.1是不是在一些地方正好0.1後小數。還有轉換在這個較高的類型即double

轉換爲float再到double,存在的信息損失也double作爲除float所以它不同於更高進動。