2017-11-16 6 views
7

私は問題に直面しました。実際に私はかなり驚いています。 番号9933272057275866を1つ増やそうとすると、自動的に2が追加されます。9933272057275866はそれが魔法の数ですか?

let test = 9933272057275866; 
let test2 = test+1; 
console.log('Before:', test); 
console.log('After:', test2); 
console.log('Sub:', test2-test); 

そして、それぞれの出力:

Before: 9933272057275866 
After: 9933272057275868 
Sub: 2 

どのようにこれを可能にすることができます 次のコードを参照してください?

環境はJavascriptです。私はHackerrankでチャレンジを提出したときにこの問題を発見し、node.jsの自分の環境でも同じことを試みました。同じ結果!

何が起こっていますか?

+3

*浮動小数点演算が壊れていません!* –

+5

'Number.isSafeInteger(9933272057275866)=== false'を読んでください:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger – Ryan

+0

@ Ryanとても素敵な記事 –

答えて

8

基本的には、64ビット(*)で正確に数値を表現できないためです。

  • 4341 A521 1037 32ED:9.93327205727586 ⨉10
  • 4341 A521 1037 32EE:9.93327205727586 ⨉10

それはそれらの間に1つの整数をスキップする方法を参照してください。 IEEE 754では、数値が高いほど数値が数値ラインに沿って広がります。浮動小数点数は近似であることに留意してください。これは、この結果を得る理由です:

0.1 + 0.2 === 0.3 // false 

IEEE 754で最大の安全な整数は、浮動小数点演算と9007199254740991.

もっと楽しい事実である:

A + B == B + A    // true, commutative, except when A or B is NaN 
(A + B) + C == A + (B + C) // false, not associative 

*それがあることを言及する価値がありますJavaScript(ECMAScript)の数値は64​​ビットIEEE 754倍で表されます。 ref

+1

'// false、not associative'よ​​りも多くは' //常に真ではない... 'ではありません。 – Kaiido

+1

@Kaiidoこれは数学的な文ですが、コードブロック内ではなくいくつかのLaTeX形式のテキストです。 –

+0

@Kaiido何らかの理由でLaTeXはSOでサポートされていませんが、他のSEサイトにあります。残念ながらそれは私ができる最善のことです。 –

関連する問題