JavaScriptと9007199254740993
こんばんわ
友達に聞かれて即答できなかったので調べてみました
9007199254740993が1減る?
タイトルの通りですが
// コレをやると console.log(9007199254740993); // こうなります 9007199254740992
実際は1減ったとかではなく
これも
for (var i = 9007199254740993; i + 100 > i; i += 1) console.log(i);
全てが 9007199254740992 になります。
理由
ECMAScriptの数値はIEEE 754の倍精度浮動小数点数という仕様になってます
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
4.3.19 Number value primitive value corresponding to a double-precision 64-bit binary format IEEE 754 value NOTE A Number value is a member of the Number type and is a direct representation of a number. 4.3.20 Number type set of all possible Number values including the special ―Not-a-Number‖ (NaN) values, positive infinity, and negative infinity
よって、暗黙bitを含めた53bitの仮数部を超えると精度を保てなくなります
console.log(9007199254740993..toString(2).length);
// => 54
@y_imayaさん
教えて頂きありがとうございました〜
ビット演算の場合
また、ビット演算は内部的に32bit整数に変換する仕様からして
// 1 << 30 Math.pow(2,30)|0; 1073741824 // 1 << 31は、32bitの2の補数表現に Math.pow(2, 31)|0; -2147483648
V8の場合31bitまではSmiで表現されるとのことですが、今度もう少し調べてみますー。
併せて知らないと詰まるネタだなぁ思いました
おしまい。
開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質
- 作者: Cody Lindley,和田祐一郎
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/06/19
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る