9999999999999999 が 10000000000000000 に変換される理由を説明できる人はいますか?
alert(9999999999999999); //10000000000000000
9999999999999999 が 10000000000000000 に変換される理由を説明できる人はいますか?
alert(9999999999999999); //10000000000000000
Javascript には整数がなく、64 ビットの浮動小数点数しかありません。浮動小数点の精度が不足しています。
Java で同様の問題を参照してください。
JavaScript には浮動小数点数のみがあり、整数はありません。
すべてのコンピューター科学者が浮動小数点演算について知っておくべきことをお読みください。
要約: 浮動小数点数には限られた精度しか含まれず、15 桁 (またはそれ以上) を超えると、丸めが行われます。
9999999999999999
JavaScript の内部では浮動小数点数として扱われます。54 ビットの精度が必要になるため、IEEE 754 の倍精度では正確に表すことができません (ビット数は log2(9999999999999999) = 53,150849512... であり、小数ビットが存在しないため、結果を切り上げる必要があります)。一方、IEEE 754 は 53 ビット (1 暗黙ビット + 仮数部の 52 明示的に格納されたビット) のみを提供します - 1 ビット少ないです。したがって、数値は単純に丸められます。
この場合、失われるビットは 1 つだけなので、54 ビットの数値でも正確に表現できます0
。奇数の 54 ビット数は、IEEE 754 のデフォルトの偏りのない丸めモードの場合、2 倍の偶数 53 ビット数である最も近い値に丸められます。
質問: JavaScript の計算結果が「不正確」になることがあります。たとえば、0.362*100 は 36.199999999999996 になります。どうすればこれを回避できますか?
回答: JavaScript は内部的に、52 ビットの仮数部と 11 ビットの指数部 (数値を格納するための IEEE 754 標準) を使用して、すべての数値を倍精度浮動小数点形式で格納します。この数値の内部表現は、上記のような予期しない結果を引き起こす可能性があります。253 = 9007199254740992 より大きいほとんどの整数は、この形式では正確に表すことができません。同様に、0.362 などの多くの小数/分数は正確に表すことができないため、上記の例では「不正確」と認識されます。これらの「不正確な」結果を避けるために、使用したデータの精度に合わせて結果を丸めることができます。
バイナリ形式の9999999999999999は、 54 桁の10001110000110111100100110111110000001111111111111111です。
以下では、この数字を Javascript IEEE-754 に変換します。これは、符号に 1 桁、バイナリ オフセット形式の仮数に 11 桁、数値自体に 52 の符号を持ちます。
バイナリ形式では最初の桁は常に1であるため、Javascript は IEEE-754 形式に保存するときに仮数部の数値の最初の桁を省略します。したがって、仮数部には00011100001101111001001101111110000001111111111111111があり、これは 53 桁であり、保持できるのは 52 桁のみです。
2 進数形式の最終的な数値は 1 0001110000110111100100110111111000001000000000000000 0 10 進数形式では 10000000000000000 になります
1 は仮数部の 52 ビットに書き込まれない最初の桁であり、次に仮数部の 52 ビットと 1 つの 0 で 54 桁を戻します。これは 10 進数で10000000000000000です