在C中,當浮動設置,使C漂浮精確?
int main(int argc, char *argv[]) {
float temp = 98.6f;
printf("%f\n", temp);
return 0;
}
它似乎總是得到一些舍入誤差,
98.599998
但是當我使其更加精確,
float temp = 96.600000f;
它仍然打印一個不同的數字。這應該如何解決?
在C中,當浮動設置,使C漂浮精確?
int main(int argc, char *argv[]) {
float temp = 98.6f;
printf("%f\n", temp);
return 0;
}
它似乎總是得到一些舍入誤差,
98.599998
但是當我使其更加精確,
float temp = 96.600000f;
它仍然打印一個不同的數字。這應該如何解決?
添加尾隨零永遠不會有所作爲。
問題是,32位浮點數不能精確表示96.6
,句號。
它不是隨機挑選數字來填補你遺漏的;它將它四捨五入到它能表達的最接近的數字。
它仍然打印一個不同的數字。這應該如何解決?
通過使用不同的數據類型,如果你想精確十進制值。
二進制浮點數是精確 - 它只是它們的精確值二進制值。例如,如果要基數3表示小數,則小數不精確。例如,如果要表示基數3中的數字,則十進制不精確。沒有精確的二進制表示形式,只有0.1個十進制,就像沒有「三分之一」的精確十進制表示形式。
這完全取決於您的要求是什麼,並使用與之匹配的數據類型。對於精確的十進制值,您可能最好使用第三方庫......或者保留一個您知道的整數邏輯上由100或10,000等等縮放的整數。
什麼是二進制浮點數? –
@EdHeal:一個浮點類型的值,浮點「浮點」是一個二進制點。例如,八分之一是二進制的0.001,可以表示爲「尾數爲1,指數爲-3」(取決於確切的表示)。 –
@JonSkeet所以它就像基數2中的小數?所以雖然'1100'是小數點後12位,'1100.01'小數點後是12.25? – tkbx
它與平臺有關,但通常像98.6這樣的數字不能完全表示。
你可以做的是使用printf
精度說明等,以顯示"%.2f"
「圓圓」的數量。
對於「_usually_像98.6這樣的數字不能完全表示」。浮點_could_應該是十進制的,然後是98.6。即G。 IEEE 754 decimal32。 – chux
沒有簡單的答案。它與浮動在記憶中的表現有關,但我們傾向於認爲它們可以代表所有實數。他們不能。如果你想精確地使用浮點數,可以考慮小於或大於範圍,而不是試圖將它們等同起來。在你的例子中,嘗試使用%f2.1(或類似的)在小數點右側打印出少量的數字。
給出的是字float。它由尾數和指數組成。該值是它可以在有限的位數中實現的最佳表示形式(以pi爲例)。
所以不要使用相等,因爲你得到舍入錯誤。你可以採取措施儘量減少他們,但這需要幾個講座和一本教科書。
順便說一句 - 不要使用花車錢。更好地使用整數並以毫米/分鐘計算東西/ ...
你的回答並不能解釋爲什麼「98.6」不能完全表示。這裏的關鍵問題不在於它是浮點數 - 它是浮點數是* binary *點,而源數據是* decimal *。 –
這是以二進制形式表示十進制數的基本限制。二進制浮點數用2的冪表示,而十進制數用10的冪表示,而C的float
根本無法精確地表示所有的十進制數。
你舉的例子數,96.1可以寫成:
96.1 = 9*10^1 + 9*10^0 + 1*10^-1
以二進制表示這一點,你可以得到整數96就好了:
96 = 1*2^6 + 1*2^5
但代表0.1是有問題基數2.前幾個二進制小數位的數值爲:
2^-1 = 0.5
2^-2 = 0.25
2^-3 = 0.125
2^-4 = 0.0625
2^-5 = 0.03125
2^-6 = 0.015625
2^-7 = 0.0078125
2^-8 = 0.00390625
2^-9 = 0.001953125
... and so on
因此,不知何故y您需要使用這些位置值的組合來加起來約爲0.1的十進制數。所以你必須以b0.0001(d0.0625)作爲第一個小於d0.1的開始,並且增加一些更小的位置值以接近和接近0.1。例如:
b0.001 = d0.125 // too high, try lower
b0.0001 = d0.0625 // too low, so add smaller places
b0.00011 = d0.09375 // good, closer... rounding error is 0.0625
b0.000111 = d0.109375 // oops, a little high
b0.00011001 = d0.09765625 // getting better - how close do you need?
...
等等 - 你明白了。因此,由於基本表示,二進制值只能近似小數。
有許多關於浮點舍入誤差和表示限制的文章。絕對值得做一些關於這個話題的背景閱讀。
有解決這個問題的一些方法:
float
但仍然意識到了限制,並精心設計了算法,以儘量減少舍入誤差*二進制*浮點數用2的冪來表示。擁有非二進制浮點數是完全可行的 - 浮點數的概念就是有一個尾數和一個指數,它在某些基礎上被解釋。例如,.NET中的System.Decimal是一個十進制浮點數。 –
請閱讀[每位計算機科學家應該瞭解的浮點算術知識](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)瞭解深入信息說明。 –
另請參見[定點算術](http://en.wikipedia.org/wiki/Fixed-point_arithmetic) - 一般不會取代浮點數,但它是解決一些問題的另一種方法。 – user2246674
另一個很好的參考:http://floating-point-gui.de/ – abelenky