2016-07-07 107 views
1

考慮這個代碼(節點V5.0.0)JavaScript如何處理大整數(超過52位)?

const a = Math.pow(2, 53) 
const b = Math.pow(2, 53) + 1 
const c = Math.pow(2, 53) + 2 

console.log(a === b) // true 
console.log(a === c) // false 

爲什麼a === b是真的嗎?

javascript可以處理的最大整數值是多少?

我正在實現隨機整數發生器高達2^64。我應該知道有什麼陷阱嗎?

+1

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_VALUE –

+0

對不起,已經修復。 – user1518183

+0

a和b是相同的數字,並且相同的數字是相同的或相等的。 – dandavis

回答

1

。:: JavaScript只支持53位整數::。

在JavaScript中的所有數字均浮點這意味着整數始終表示爲

sign × mantissa × 2exponent 

尾數具有53個比特。你可以使用指數來獲得更高的整數,但是它們不會再連續。例如,您通常需要將尾數乘以2(指數1)才能達到第54位。

但是,如果乘以二,你只能夠代表每秒整數:在添加過程中

Math.pow(2, 53)  // 54 bits 9007199254740992 
Math.pow(2, 53) + 1 // 9007199254740992 
Math.pow(2, 53) + 2 //9007199254740994 
Math.pow(2, 53) + 3 //9007199254740996 
Math.pow(2, 53) + 4 //9007199254740996 

舍入影響使事情變得不可預測奇數增量(+1與+3)。實際的表示有點複雜,但這種解釋應該有助於你理解基本問題。

您可以安全地使用strint庫來對字符串中的大整數進行編碼並對它們執行算術運算。

Here是整篇文章。

3

回答你的第二個問題,這是你最大安全整數在JavaScript:

console.log(Number.MAX_SAFE_INTEGER); 

其餘全部是寫在MDN

MAX_SAFE_INTEGER不斷有9007199254740991值。推理該數字的 是JavaScript使用雙精度 IEEE 754中指定的浮點格式數字,並且只能使用 安全地表示-(253 - 1)253 - 1之間的數字。

本文中的安全性指的是準確表示整數 並正確比較它們的能力。例如, Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2將 評估爲true,這在數學上是不正確的。有關更多信息,請參閱 Number.isSafeInteger()

2

javascript如何處理大整數?

JS沒有整數。 JS數字是64位浮點數。它們存儲爲尾數和指數。

精度由尾數給出,幅度由指數給出。

如果您的號碼需要比可以存儲在尾數的精度更高的精度,最不重要的位將被截斷。

9007199254740992; // 9007199254740992 
(9007199254740992).toString(2); 
// "100000000000000000000000000000000000000000000000000000" 
// \  \     ...     /\ 
// 1  10          53 54 
// The 54-th is not stored, but is not a problem because it's 0 

9007199254740993; // 9007199254740992 
(9007199254740993).toString(2); 
// "100000000000000000000000000000000000000000000000000000" 
// \  \     ...     /\ 
// 1  10          53 54 
// The 54-th bit should be 1, but the mantissa only has 53 bits! 

9007199254740994; // 9007199254740994 
(9007199254740994).toString(2); 
// "100000000000000000000000000000000000000000000000000010" 
// \  \     ...     /\ 
// 1  10          53 54 
// The 54-th is not stored, but is not a problem because it's 0 

然後,您可以存儲所有這些整數:

-9007199254740992, -9007199254740991, ..., 9007199254740991, 9007199254740992 

第二個被稱爲minimum safe integer

Number.MIN_SAFE_INTEGER值是最小的整數n使得 使得n和n - 1都可以精確地表示爲一個數值。

Number.MIN_SAFE_INTEGER值是-9007199254740991 ( - (2 -1))。

第二最後一個被稱爲maximum safe integer

Number.MAX_SAFE_INTEGER的值是最大的整數n如 即n和n + 1都精確表示爲數字值。

Number.MAX_SAFE_INTEGER的值是9007199254740991 (2 -1)。

0

Number.MAX_VALUE會告訴你在你的JS實現中可表示的最大浮點值。答案可能是:1.7976931348623157e + 308。但這並不意味着每個10^308以下的整數都可以精確表示。正如您的示例代碼所示,除了2^53之外,只有偶數可以表示,並且隨着您走出數字線,差距會變得更大。

如果您需要大於2^53的精確整數,您可能需要使用bignum包,該包允許任意大的整數(在可用內存的範圍內)。我碰巧知道兩個包:

BigInt by Leemon

Crunch