2014-11-04 43 views
-1

我正在試圖創建一個使我能夠打印浮點數的函數。 現在,我遇到了兩種奇怪的行爲: 有時,像1.3這樣的值出現爲1.2999999而不是1.3000000,有時像1.234567這樣的值出現爲1.2345672而不是1.2345670。C - 打印一個浮點數 - 當將其轉換爲int時丟失精度

這裏的源代碼:

int  ft_putflt(float f) 
{ 
    int  ret; 
    int  intpart; 
    int  i; 

    ret = 0; 
    i = 0; 
    intpart = (int)f; 
    ft_putnbr(intpart); 
    ret = ft_nbrlen(intpart) + 8; 
    write(1, ".", 1); 
    while (i++ < 7) 
    { 
     f *= 10; 
     ft_putchar(48 + ((int)f % 10)); 
    } 
    return (ret); 
} 

ft_putnbr是OK AFAIK。對於「write(1,&c,1)」,ft_putchar是一個簡單的調用。

test values (value : output) 

1.234567 : 1.2345672 (!) 

1.2345670 : 1.2345672 (!) 

1.0000001 : 1.0000001 OK 

0.1234567 : 0.1234567 OK 

0.67  : 0.6700000 OK 

1.3  : 1.3000000 OK (fixed it) 

1.321012 : 1.3210119 (!) 

1.3210121 : 1.3210122 (!) 

這一切都對我來說似乎有點神祕......當鑄造到int可能失去精度?

+2

沒有那麼多的精度損失,因爲缺乏精確性開始。 「float」只能精確地表示7位小數。如果你想要更多,請嘗試'雙'。 – 2014-11-04 22:43:28

+3

歡迎來到浮點數學。您注意到的任何「症狀」都不是意外的或異常的。 – 2014-11-04 22:45:09

+0

哼...有沒有辦法解決這些「症狀」? – SwiX 2014-11-04 22:48:35

回答

1

是的,當弄錯浮標和整數時,你會失去精度。

如果兩個浮點數的大小不同,並且都使用完整的精度範圍(大約7位十進制數字),那麼是的,您會在最後的地方看到一些損失,因爲浮點數以(sign)尾數)×2 (指數)。如果兩個值具有不同的指數,你加他們,那麼較小的值會得到降低到數字的尾數(因爲它必須適應大的指數):

PS> [float]([float]0.0000001 + [float]1) 
1 

關於整數,正常32位整數能夠精確地表示與浮點不完全匹配的值。浮動仍然可以存儲大約相同的數字,但不再精確。當然,這隻適用於足夠大的數字,我。即長度超過24位。由於浮點數有24位精度,(32位)整數有32位浮點數,浮點數仍能保留幅度和大部分有效數字,但最後的地方可能會有所不同:

PS> [float]2100000050 + [float]100 
2100000100 
1

這是使用有限精度數值表示方案的固有特性。給定任何可以表示的數字,A,有一些數字是大於A的可以表示的最小數字,稱爲B.A和B之間的數字不能精確表示,必須近似。

例如,讓我們考慮使用六位十進制數字,因爲這是一個更容易理解的系統作爲起點。如果A是.333333,那麼B是.333334。 A和B之間的數字,如1/3,不能準確表示。所以如果你拿1/3並將它加到自身兩次(或乘以3),你將得到.999999,而不是1.你應該期望在表示的極限處看到不精確。

相關問題