為什麼JavaScript裡面0.1+0.2 === 0.3是false
0.1+0.2 === 0.3 //返回是false, 這是為什麼呢??
我們知道浮點數計算是不精確的,上面的返回式實際上是這樣的:
0.1 + 0.2 = 0.30000000000000004
0.1 + 0.2 - 0.3 = 5.551115123125783e-17
5.551115123125783e-17.toFixed(20) = '0.00000000000000005551'
在JavaScript的新規範ES6加入了一個新的東西-->Number.EPSILON
Number.EPSILON是在Number物件上面,新增一個極小的常量。根據規格,它表示 1 與大於 1 的最小浮點數之間的差。
對於 64 位浮點數(double)來說,大於 1 的最小浮點數相當於二進位制的 1.00..001 ,小數點後面有連續 51 個零。這個值減去 1 之後,就等於 2 的-52 次方。
Number.EPSILON 實際上是 JavaScript 能夠表示的最小精度。誤差如果小於這個值,就可以認為已經沒有意義了,即不存在誤差了。
引入一個這麼小的量的目的,在於為浮點數計算,設定一個誤差範圍。
好了,我們來解決上面的浮點數計算的問題:
Number.EPSILON 可以用來設定“能夠接受的誤差範圍”。比如,誤差範圍設為 2 的-50 次方(即 Number.EPSILON * Math.pow(2, 2) ),即如果兩個浮點數的差小於這個值,我們就認為這兩個浮點數相等。
5.551115123125783e-17 < Number.EPSILON * Math.pow(2, 2) // true
因此, Number.EPSILON 的實質是一個可以接受的最小誤差範圍。
function withinErrorMargin (left, right) { return Math.abs(left - right) < Number.EPSILON * Math.pow(2, 2); }
0.1 + 0.2 === 0.3 // false
withinErrorMargin(0.1 + 0.2, 0.3) // true
1.1 + 1.3 === 2.4 // false
withinErrorMargin(1.1 + 1.3, 2.4) // true
上面的程式碼為浮點數運算,部署了一個誤差檢查函式。
文章引用自ES6標準。