簡體   English   中英

了解浮點問題

[英]Understanding floating point problems

有人可以幫我理解如何確定浮點限制何時會導致計算錯誤。 例如以下代碼。

CalculateTotalTax = function (TaxRate, TaxFreePrice) {
     return ((parseFloat(TaxFreePrice) / 100) * parseFloat(TaxRate)).toFixed(4);
};

我無法輸入任何導致我這個方法的結果不正確的值。 如果我刪除toFixed(4),我可以看到計算開始失去准確性的位置(大約在小數點后6位)。 盡管如此,我對浮點數的理解是,即使是小數字有時也無法表示或者我誤解了,並且可以精確地表示4位小數(例如)。

MSDN解釋浮動本身 ......

這意味着它們不能保存任何不是二進制分數的數量的精確表示(形式為k /(2 ^ n),其中k和n是整數)

現在我假設這適用於所有浮點數(包括javascript中使用的浮點數)。

從根本上說,我的問題歸結為這一點。 如何確定任何特定方法是否容易受到浮點運算中的錯誤的影響,這些錯誤將以何種精度實現,以及產生這些錯誤需要哪些輸入?

希望我所要求的是有道理的。

首先閱讀每個計算機科學家應該知道的浮點數http//docs.sun.com/source/806-3568/ncg_goldberg.html

簡短回答:雙精度浮點數(這是JavaScript中的默認值)具有大約16個十進制數字的精度。 舍入可能因平台而異。 如果你得到始終正確的答案絕對必要,你應該自己做理性算術(這不需要很難 - 對於貨幣,也許你可以乘以100來存儲整數的分數)。

但是如果能夠以高精度得到答案就足夠了,漂浮物應該足夠好,特別是雙精度。

在處理浮動時,你應該有兩個重要的事情:

1-你應該知道機器epsilon 要知道你有多精確。

2-您不應該假設兩個值在基數10中相等,它們在具有精度限制的機器中的基數2中相等

if ((6.0 / 10.0) / 3.0 != .2) {
        cout << "gotcha" << endl;
}

數字2可能足夠令人信服,可以避免比較浮點數的相等性,而是可以使用閾值和大於或小於運算符進行比較

其他答案指出了理解這個問題的良好資源。 如果您在代碼中實際使用貨幣值(如您的示例中所示),則應該更喜歡Decimal類型(.Net中的System.Decimal)。 這些將避免使用浮點數和更好地匹配域的一些舍入問題。

不,小數位數與可以表示的內容無關。

嘗試.1 * 3,或162.295 / 10,或24.0 + 47.98。 那些在JS中失敗了。 但是,24.0 * 47.98不會失敗。

因此,要回答您的三個問題,任何精度的任何操作都可能存在漏洞。 一個給定的輸入是否會是一個我不知道如何回答的問題,但我有預感有很多因素。 1)實際答案與最近的二進制分數有多接近。 2)執行計算的發動機的精度。 3)用於執行計算的方法(例如,乘以比特移位可能得到與乘以重復加法不同的結果)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM