2012-11-06 69 views
3

我遇到一個奇怪的問題,在我的單元測試給我帶來了在JavaScript中意外舍入的結果之一:在JavaScript或IEEE-754中舍入怪癖?

(2.005).toFixed(2) 
// produces "2.00" 

(2.00501).toFixed(2) 
// produces "2.01" 

起初我懷疑這是一個唯一的Webkit的問題,但它在壁虎repros這意味着對我來說這是ECMA-262或IEEE-754的預期副作用。我假設2.005的二進制表示會稍微少一些?或者ECMA-262是否規定了toFixed的循環方法?

任何人都在意對引擎蓋下正在發生的事情有所瞭解,以便讓我安心?

更新:感謝您的意見。

我應該補充一點,讓我有點緊張的事情之一是在Webkit dtoa.cpp的快速搜索中發現的意見,這似乎暗示有多條路徑可以四捨五入,而且開發人員並不確定它是如何實現的工作,包括相關FIXME

https://trac.webkit.org/browser/trunk/Source/WTF/wtf/dtoa.cpp#L1110

而且,並不在於它意味着很多,但IE9輪次如我所料,這意味着它要麼是不是ECMA-262的一部分,或者它們有一個bug。

+0

很可能'2.005'實際上是二進制浮點型的'2.004999999 ...'。 – Mysticial

+1

2.00499999999999989341858963598497211933135986328125 –

+0

也許[看看這裏](http://stackoverflow.com/questions/1458633/elegant-workaround-for-javascript-floating-point-number-problem)有很多關於這個問題的文章的鏈接,最重要的鏈接是[可能的重複](http://stackoverflow.com/questions/588004/is-javascripts-math-broken) –

回答

5

,如果說明書沒有因爲ECMA 262草案(5.1版,2011年3月),(2.005).toFixed(2)必須返回字符串"2.00",因爲「數字值」的Rev. 6變化是相對應的

原始值到雙精度64位的二進制格式的IEEE 754值

和數字文本的解釋在7.8.3和8.5被規定爲符合IEEE 754「舍入到最近」模式(與領帶四捨五入到甚至有效數字),這對於2.005結果LTS在值

x = 4514858626438922 * 2^(-51) = 2.00499999999999989341858963598497211933135986328125 

在第15.7.4.5與toFixed,相關步驟8.一個交易。是:

n是整數爲其中n÷10 ˚F確切數學值 - x是接近零越好。如果有兩個這樣的n,請選擇較大的n

2.00 - x2.01 - x接近於零,所以n必須是200在這裏。然後以自然的方式轉換爲字符串。

另外,這並不意味着它意味着很多,但IE9按照我的預期舍入它,這意味着它不是ECMA-262的一部分,或者它們有錯誤。

一個錯誤。也許他們試圖用簡單的方法,並且與10^digits一起繁殖。x*100正好是200.5,這樣就會產生一串"2.01"

+0

完美。這正是我所期待的。謝謝! – mckamey