2016-08-30 90 views
1

下面的代碼:如何乘以ANSI C中的浮點數?

float numberForFactorial; 
    float floatingPart = 1.400000; 
    int integralPart = 1; 

    numberForFactorial = ((floatingPart) - (float)integralPart) * 10; 

    printf("%d", (int)numberForFactorial); 

返回3而不是4.你能解釋我爲什麼?

+0

可能因爲'1.40000'被內部存儲爲'1.399999'或類似的東西。如預期的那樣,(int)3.99999'爲'3'。 –

+0

當你做'printf(「%0.6f \ n」,floatingPart)時,你會得到什麼;'? –

+0

要擴展@ MadPhysicist的評論,從浮點到整數的轉換將截斷爲零。 –

回答

2

最靠近1.400000float略小於1.4。您可以驗證通過做

printf("%0.8hf\n", floatingPart); 

ideone結果是1.39999998。這意味着小數點後第一位數字的10倍是3

要避免此問題,請使用舍入而不是截斷。一個簡單的方法,以圓是截斷前加入一半:

printf("%d", (int)(numberForFactorial + 0.5f)); 

將打印4如您所期望。您也可以使用roundrint,lroundmodf獲得相同的結果:https://www.gnu.org/software/libc/manual/html_node/Rounding-Functions.html。舍入是一個複雜的主題,所以選擇最適合您的情況約束的方法。

+0

oh f ** k ..現在我明白了爲什麼...... – Nikitas

+0

@Nikitas。如果解釋了需要解釋的內容,請隨意選擇此答案。 –

+0

是啊,花車是a **中的痛苦。 –

2

這是由於浮點值的二進制表示。更具體地,0.42/5不能與尾數表示爲任何組合等之和1/2 + 1/4 1/8 + + ...

字面1.400000被存儲爲在其二進制更接近於1.399999976158142表示。轉換到int截斷非整數部分,給出三個作爲最終結果。要想迂迴,C標準不要求浮點數據類型的基於二進制的表示,但IEEE 754事實上是當今計算中的標準。

+1

希望你不介意我的編輯。 +1 –

+0

嗯...是的,當我學習「計算機系統程序員的視角」第三版,第2章,第110頁時,我知道1/2 + 1/4 + 1/8的事情 – Nikitas