float a=67107842,b=512;
float c=a/b;
printf("%lf\n",c);
爲什麼c
131070.000000而不是正確的值131070.00390625?爲什麼我的浮動除法0.00390625?
float a=67107842,b=512;
float c=a/b;
printf("%lf\n",c);
爲什麼c
131070.000000而不是正確的值131070.00390625?爲什麼我的浮動除法0.00390625?
您的編譯器的float
類型可能使用32位IEEE 754單精度格式。
67107842是一個26比特的二進制數:
11111111111111110000000010
單精度格式表示最數作爲1.x
通過兩個一些(正或負)功率,其中23位被二進制後存儲multipled與暗示的領先1.
(非常小的數字是例外)。
但是67107842在二進制位之後將需要24位(將被表示爲1.111111111111111000000001
倍增2 )。由於只有23位存儲空間,因此最後的1
會丟失。因此,它是錯在這種情況下a
的價值,而不是分裂 - a
實際上包含67107840(11111111111111110000000000
),這正好是131070 * 512
你可以看到這一點,如果你打印a
還有:
printf("%lf %lf %lf\n", a, b, c);
給出
67107840.000000 512.000000 131070.000000
ideone的編譯器使用像您所描述的'float':http://ideone.com/pA0My – pmg 2011-04-02 15:48:17
嘗試更改a和c鍵入「double」,而不是float。這會給你更好的精度/準確性。 (浮點數大約有6位左右有效數字;雙數有兩倍以上)
甲float
通常使用32位IEEE-754單精度表示,並且是良好的僅約6顯著小數音響gures。 A double
適用於15,支持80位long double
可獲得20位有效數字。
請注意,在某些編譯器中,double
和long double
之間沒有區別,甚至完全不支持long double
。
一個解決方案是使用任意精度的數字庫,或者使用十進制浮點庫而不是內置的二進制浮點支持。十進制浮點本質上並不精確(儘管通常這種類型的庫支持更大,更精確的類型),但不會顯示在顯示二進制浮點值的十進制表示時發生的人爲影響。十進制浮點數也可能要慢得多,因爲它通常不是用硬件實現的。
浮點數字並不準確。 – driis 2011-04-02 13:36:08
在閱讀浮點數學之前,您應該閱讀以下內容:http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html。 – 2011-04-02 13:49:42
如果你沒有足夠的理由使用'float',那麼總是比較喜歡'double'。一個足夠好的理由**不是**,「因爲它們更快」(大多是假的);或「因爲他們更小」(大部分是真的); 「或者因爲double需要6個字符而浮動需要5個」。 – pmg 2011-04-02 13:58:27