2012-06-06 26 views
4

爲什麼從9.999999999999999開始的科學記數法中的某些數字四捨五入爲1而其他數字保持不變?爲什麼一些科學數字會自動舍入而其他數字不是?

例如,在Google Chrome 20中會發生以下情況。

(9.999999999999999e+306).toString() === "9.999999999999999e+306" // true

(9.999999999999999e+303).toString() === "1e+304" // true

這是爲什麼?這是浮點問題嗎?

然而奇怪的是,在Opera 11.64 (1e23).toString() === "9.999999999999999e+22"。我試圖向Opera報告1e23錯誤,但沒有人回覆。

現場演示這裏:演示

var console = console || {}; 
console.logToBody = function(str){ 
    document.body.innerHTML += "" + str + "<br/>"; 
};  
var parts = ["9.999999999999999e", 310 ], tmp, tmp2; 
while(parts[1]--){ 
    tmp = +(parts.join('')); 
    if(/9.9{3,}e/.test(+tmp)){ 
     console.logToBody(tmp + " doesn't convert to " + (+tmp).toPrecision(1)); 
    } 
    tmp2 = "1e"+parts[1]; 
    //Carakan Javascript Engine Math BUG: 
    if(!/^1e*/.test(+tmp2)){ 
     console.logToBody(tmp2 + " = " + (+tmp2) + " in the runtime environment."); 
    } 
} 
+3

因爲浮點數實際上是[非常大的分數的近似值](http://en.m.wikipedia.org/wiki/Double-precision_floating-point_format) –

+0

@minitech:'9.999999999999999e + 22'是如何不同從'9.999999999999999e + 306'? – zerkms

+0

@minitech不在歌劇中。 –

回答

3

這是因爲浮點數有時近似的 http://jsfiddle.net/3ekDK/3/

的源代碼。有些數字不能用浮點格式表示,即二進制小數,因此它們近似於http://en.wikipedia.org/wiki/IEEE_754-2008

這就是爲什麼你不應該依賴浮點算術而不捨入它。一個簡單的例子如下:

> 20.61 - .1 
    20.509999999999998 

這裏的http://www.randelshofer.ch/fhw/gri/float.html#chapterfloatingpointformat

普通十進制 178.125

科學小數 1.78125ë102

科學浮點格式的很好的解釋二進制 1.0110010001 E 2111

+0

它與小數部分更相關,不是嗎? – zerkms

+0

@zerkms - 請記住,小數部分是二進制的,在大多數情況下並不完全翻譯成小數。 –

+2

@熱舔:我這樣做,但我不明白爲什麼指數值會改變最終結果。 '9.999999999999999e + 306' vs'9.999999999999999e + 303' ---爲什麼我們在這兩種情況下看到不同的行爲? – zerkms

相關問題