6

JavaScript の数値を処理しているときに、次の奇妙な動作を見つけました。

var baseNum = Math.pow(2, 53);
console.log(baseNum); //prints 9007199254740992

console.log(baseNum + 1); //prints 9007199254740992 again!

console.log(baseNum + 2); //prints 9007199254740994, 2 more than +1

console.log(baseNum + 3) // prints 9007199254740996, 2 more than +2
console.log(baseNum + 4) // prints 9007199254740996, same as +3

ここで何が起きてるの?JavaScript は最大までの数値しか表現できないことは理解していますが2^53(内部的に「double」になっていますか?)、なぜこのような動作をするのでしょうか?

が実際の最大値である場合2^53、なぜNumber.MAX_VALUE( 1.7976931348623157e+308) があるのですか?

4

3 に答える 3

10

数は本当に倍です。仮数には 52 ビットがあります (倍精度に関するソースおよび追加情報)。したがって、2^53 を格納すると 1 ビットが切り捨てられます。

数値は、3 つの符号ビット (かなり単純明快) と、他の 2 つの要素 (仮数 M と指数 E) を使用して格納されます。数値は次のように計算されます。

(1 + M/2^53) * 2^(E-1023)

細かな部分は少しずれているかもしれませんが、基本的な考え方はそこにあります。したがって、数値が 2^53 の場合、2^(E-1023) = 2^53 となり、M には 52 ビットしかないため、最下位ビットを表すことができなくなります。

于 2012-09-26T05:46:03.813 に答える
5

@CrazyCastaが出した答えは良いです。

追加する唯一のことは、2番目の質問に追加することです。

が実用的な最大値である場合2^53、なぜNumber.MAX_VALUE1.7976931348623157e+308)があるのですか?

あなたが示したように、それはより大きな数を保存することができ2^53ますが、精度はより悪いです2^0。数値が大きくなるにつれて、精度はますます低下します。

したがって、の最大値はNumber.MAX_VALUE、それが表すことができる「最大の」値を意味します。2^1ただし、精度がまたはに近い値と同じであるという意味ではありません2^53

これに対する当然の結果として、Numberに含めることができるNumber.MIN_VALUE最小の値があります。最もネガティブではありません。つまり、これはゼロに最も近い非ゼロの数値です:(5.00E-324正の数値であることに注意してください)。

于 2012-09-26T05:52:13.483 に答える
2

longに格納できる最大値は、longに正確に格納できる最大値よりもはるかに大きくなります。浮動小数点数の有効桁数の最大数は固定されていますが、数の大きさははるかに大きくなる可能性があります。

指数(2の累乗)に割り当てられた特定の数のビットがあり、それは残りのビットに格納されている仮数によって暗黙的に乗算されます。特定のポイントを超えると、精度が低下しますが、指数をインクリメントし続けて、ますます大きな大きさを表すことができます。

于 2012-09-26T05:50:38.117 に答える