2017-11-04 178 views
2

我有兩個數字要比較。以下示例中的數字是在兩個不同系統中計算的26^26的結果。其中之一是我的JavaScript代碼。在Javascript中比較大數字

然而,比較這兩個數字,當我結束了這樣的事情:

AssertionError [ERR_ASSERTION]: 4.0329146112660565e+26 == 4.0329146112661e+26 

他們顯然不是平等的,但理論上他們應該。

什麼是正確的方式來執行平等大數字在JavaScript(即使它是一個近似)?

+1

https://github.com/MikeMcl/bignumber。js/ – shotgunner

+0

您可以將數字轉換爲字符串,然後執行比較 – guest271314

+1

** equal **表示什麼意思?嚴格平等?或等於一些數字?或者等於固定的精度?或可以相互舍入的數字?請指定 –

回答

1

var a = 4.0329146112660565e + 26;

var b = 4.0329146112661e + 26;

一個= Math.round(A/10E + 20)* 10E + 20

B = Math.round(B/10E + 20)* 10E + 20

一個== B;

+0

@Daniel Lord謝謝! '10e + 20'似乎有點神奇。你介意解釋它背後的邏輯嗎?這個解決方案與@GitaarLAB有關'Number.MAX_SAFE_INTEGER'的建議相結合,對我來說是個訣竅。 'Math.round(4.0329146112661e + 26/Number.MAX_SAFE_INTEGER)* Number.MAX_SAFE_INTEGER;' – Wazeem

+0

@Sam D.似乎你希望精度小於12,因爲這是浮點數不同的地方。此解決方案的精度爲26 - 20 + 1 = 7。精度爲浮點數7邏輯。改變20以獲得或失去比較的精度。 –

+0

爲什麼要將'20'和'26'轉換爲數字,它已經是一個數字:'10e + 20 == 10e20' – dandavis

3

如果你想要做的是確定兩個數字是否幾乎相等,你將不得不提出你的誤差範圍。一種方法是計算數字之間的差異,然後確定差異是否顯着。

所以,從以前的數字,我們可以通過減法來評估這些數字之間的差異。由於我們並不關心這種差異的跡象,所以我會繼續前進並獲得差異的絕對值。

Math.abs(4.0329146112660565e+26 - 4.0329146112661e+26) === 4329327034368 

(旁註:當你想比較值現在不是解釋爲什麼的時候,但在JavaScript中的==操作符有混亂和容易出錯的行爲,使用===)

這種差異是一個很大的數字,但與我們的數字有多大有關,這是相當微不足道的。直觀地說,我很想除以最小的我們原來數之差,像這樣:

4329327034368/4.0329146112660565e+26 === 1.0734983136696987e-14 

這看起來像一個非常小的數目。用一堆值重複同樣的操作,你應該能夠確定你想要的誤差範圍。然後,你所要做的就是用任意數字執行相同的操作,看看這個「差異比率」是否足夠小。

function similar(a, b) { 
    let diff = Math.abs(a - b); 
    let smallest = Math.min(Math.abs(a), Math.abs(b)); 
    let ratio = diff/smallest; 
    return ratio < MARGIN_OF_ERROR; 
} 

現在我只是想出了確定兩個數字之間差異重要性的方法。計算它可能不是一個非常聰明的方法,它可能適用於某些情況而不適用於其他情況。但總的想法是,你必須做出一個函數,用你自己定義的「close」來確定兩個值是否足夠接近。

但請注意,JavaScript是您可以進行數學運算的最差的語言之一。當整數超出Number.MAX_SAFE_INT(根據Chrome瀏覽器似乎爲9007199254740991,不確定它在瀏覽器之間或不同瀏覽器之間或如果這是一個標準化常數)。

+1

標準化常量! IEEE 754 float的自然結果:記住咒語,只存儲53個FIRST位(和一個指數)編輯:我們不包括最後可能值(但減去一個)的原因是因爲我們希望SAFE int,而我們不能區分2 ** 53 + 1從2 ** 53 – GitaarLAB

+0

這實際上是**相對**精度,而不是**固定**,但是,它肯定可以幫助 –

+1

旁註:沒有錯誤的JavaScript數學(I做很多)。只要瞭解只有一個數字類型:IEEE 747 64位浮點數。儘管你仍然有我的+1!編輯:只要你想表示的值不需要超過53個有效位,你甚至可以用大於該值的數字進行可靠的數學運算!一旦明白你可以使用本機號碼來實現非常有趣的算法(通常是二進制) – GitaarLAB