這裏的,我不理解的代碼部分:爲什麼劃分結果會因演員陣容而異?
byte b1 = (byte)(64/0.8f); // b1 is 79
int b2 = (int)(64/0.8f); // b2 is 79
float fl = (64/0.8f); // fl is 80
爲什麼前兩個計算關閉的一個?我應該如何執行這個操作,所以它的快速和正確?
編輯:我需要在字節
這裏的,我不理解的代碼部分:爲什麼劃分結果會因演員陣容而異?
byte b1 = (byte)(64/0.8f); // b1 is 79
int b2 = (int)(64/0.8f); // b2 is 79
float fl = (64/0.8f); // fl is 80
爲什麼前兩個計算關閉的一個?我應該如何執行這個操作,所以它的快速和正確?
編輯:我需要在字節
編輯:不完全正確,請參閱:Why does a division result differ based on the cast type? (Followup)
四捨五入問題:通過轉換爲字節/ INT,你剪輯的小數位。
但64/0.8
不應該導致任何小數位?錯誤:由於浮點數的性質,0.8f不能完全像內存中那樣表示;它被存儲爲接近0.8f(但不完全)。見Floating point inaccuracy examples或類似的線程。因此,計算結果不是80.0f,而是79.xxx,其中xxx接近於1,但仍不完全爲1。
您可以通過鍵入以下到即時窗口在Visual Studio中驗證這一點:
(64/0.8f)
80.0
(64/0.8f) - 80
-0.0000011920929
100 * 0.8f - 80
0.0000011920929
您可以通過使用四捨五入解決這個問題:
byte b1 = (byte)(64/0.8f + 0.5f);
int b2 = (int)(64/0.8f + 0.5f);
float fl = (64/0.8f);
80.0f可以表示得很好。然而,0.8f不能,所以你實際上並沒有得到80.0f。 – harold 2014-09-06 18:30:33
感謝您的追捕 - 我相應地解決了我的問題。 – Matthias 2014-09-06 18:36:13
請查看我的後續問題:http://stackoverflow.com/questions/25703864/why-does-a-division-result-differ-based-on-the-cast-type-followup我得到了二進制(64/0.8f)並反向工作,它確實等於80。 – ConditionRacer 2014-09-06 19:39:26
結果要理解這個問題,你需要了解浮點表示和操作的基本知識。
0.8f不能在內存中使用浮點數精確表示。
在數學中,64/0.8等於80 在浮點算術,60/0.8等於近似80
當你施放一個浮子的整數或一個字節,僅數的整數部分是保持。在你的情況下,浮點除法的不精確結果略小於80,因此轉換爲整數產生79.
如果你需要一個整數結果,我建議你四捨五入而不是轉換結果。 一種方式來做到這一點是使用下面的函數,通過四捨五入到最接近的整數轉換爲整數:
Convert.ToInt32(64/0.8f);
恐怕快速和正確正處在這樣的情況下勝算。
由於the underlying representation in our CPU architectures,二進制浮點運算幾乎總是會產生小的錯誤。所以在你的初始表達式中,你實際上得到的值比數學上正確的值小一點。如果你期望一個整數作爲特定數學運算的結果,並且你得到了一個非常接近的數字,你可以使用Math.Round(Double, MidpointRounding)
方法來執行正確的舍入並彌補小錯誤(並確保你選擇了the MidpointRounding
strategy you expect)。
簡單鑄造結果的類型,如byte
或int
不做四捨五入 - 它只是切斷小數部分(甚至1.99999f
將成爲1
當你只是將它轉換爲這些類型)。
十進制浮點運算速度較慢且內存密集程度較高,但不會導致這些錯誤。要執行此操作,請使用文字decimal
而不是float
(例如64/0.8m
)。
decimal
。double
。float
。
我編輯了自己的冠軍。請參閱:「[應該在其標題中包含」標籤「](http://meta.stackexchange.com/questions/19190/)」,其中的共識是「不,他們不應該」。 – 2014-09-06 18:24:47
Jon Skeet的這篇文章應該涵蓋你的問題:http://csharpindepth.com/articles/general/floatingpoint.aspx – Warlock 2014-09-06 19:02:20