web-dev-qa-db-ja.com

数値を精度を落とさずに取得できるJavaScriptの最大の整数値は何ですか?

これは言語によって定義されていますか?定義された最大値はありますか?ブラウザによって違いますか?

886
TALlama

+/- 9007199254740991

ECMAセクション8.5 - 番号

大きさが2以下であるすべての正および負の整数に注意してください。53 Number型で表現できます(実際、整数0は+ 0と-0の2つの表現を持ちます)。

それらは64ビットの浮動小数点値で、最大の正確な整数値は2です。53-1、または9007199254740991。 ES6では、これは Number.MAX_SAFE_INTEGER として定義されています。

ビット演算子とシフト演算子は32ビット整数に作用するので、その場合、最大安全整数は2です。31-1、または2147483647。


var x = 9007199254740992;
var y = -x;
x == x + 1; // true !
y == y - 1; // also true !
// Arithmetic operators work, but bitwise/shifts only operate on int32:
x / 2;      // 4503599627370496
x >> 1;     // 0
x | 1;      // 1

番号9007199254740992の主題に関するテクニカルノート:この値には厳密なIEEE-754表現があり、この値を変数から割り当てたり読んだりすることができますので、{非常に慎重に}選択したアプリケーションについてこの値以下の整数は、これを最大値として扱うことができます。

一般的に、論理値9007199254740992または9007199254740993のどちらをエンコードしているかはあいまいなので、このIEEE-754値は不正確なものとして扱う必要があります。

811
Jimmy

> = ES6: Number.MIN_SAFE_INTEGER; Number.MAX_SAFE_INTEGER;

<= ES5

からの参照Number.MAX_VALUE; Number.MIN_VALUE;

console.log('MIN_VALUE', Number.MIN_VALUE);
console.log('MAX_VALUE', Number.MAX_VALUE);

console.log('MIN_SAFE_INTEGER', Number.MIN_SAFE_INTEGER); //ES6
console.log('MAX_SAFE_INTEGER', Number.MAX_SAFE_INTEGER); //ES6
441
Peter Bailey

2です53 == 9 007 199 254 740992。これは、Numberが52ビットの仮数に浮動小数点として格納されるためです。

最小値は-253

これは楽しいことが起こるのです。

Math.pow(2, 53) == Math.pow(2, 53) + 1
>> true

そして危険かもしれません:)

var MAX_INT = Math.pow(2, 53); // 9 007 199 254 740 992
for (var i = MAX_INT; i < MAX_INT + 2; ++i) {
    // infinite loop
}

さらに読む: http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html

106
Vjeux

JavaScriptでは、Infinityという番号があります。

例:

(Infinity>100)
=> true

// Also worth noting
Infinity - 1 == Infinity
=> true

Math.pow(2,1024) === Infinity
=> true

このトピックに関するいくつかの質問にはこれで十分かもしれません。

53
BananaNeil

ジミーの答え 連続JavaScript整数スペクトルを-9007199254740992から9007199254740992包括的(ごめんなさい9007199254740993、あなたは9007199254740993であると思うかもしれませんが、間違っています!以下または jsfiddleのデモ)。

document.write(9007199254740993);

ただし、これをプログラムで検索/証明する回答はありません( his answer で言及された28.56年で終わるCoolAJ86を除く;)、ここでそれを行うより少し効率的な方法があります(正確には、約28.559999999968312年だけ効率的です:)と テストフィドル

/**
 * Checks if adding/subtracting one to/from a number yields the correct result.
 *
 * @param number The number to test
 * @return true if you can add/subtract 1, false otherwise.
 */
var canAddSubtractOneFromNumber = function(number) {
    var numMinusOne = number - 1;
    var numPlusOne = number + 1;
    
    return ((number - numMinusOne) === 1) && ((number - numPlusOne) === -1);
}

//Find the highest number
var highestNumber = 3; //Start with an integer 1 or higher

//Get a number higher than the valid integer range
while (canAddSubtractOneFromNumber(highestNumber)) {
    highestNumber *= 2;
}

//Find the lowest number you can't add/subtract 1 from
var numToSubtract = highestNumber / 4;
while (numToSubtract >= 1) {
    while (!canAddSubtractOneFromNumber(highestNumber - numToSubtract)) {
        highestNumber = highestNumber - numToSubtract;
    }
    
    numToSubtract /= 2;
}        

//And there was much rejoicing.  Yay.    
console.log('HighestNumber = ' + highestNumber);
40
Briguy37

安全であるために

var MAX_INT = 4294967295;

推論

もっと実用的なアプローチでx + 1 === xになる値を見つけるのが賢いと思います。

私のマシンは毎秒1000万ほどしかカウントできません...だから私は28.56年後に決定的な答えをポストバックします。

あなたがそれほど長く待つことができないならば、私はそれを賭けるつもりです

  • あなたのループのほとんどは28.56年間実行されません
  • 9007199254740992 === Math.pow(2, 53) + 1は十分な証拠です
  • ビットシフトに関して予想される問題を回避するために、Math.pow(2,32) - 1である4294967295に固執するべきです。

x + 1 === xを探す:

(function () {
  "use strict";

  var x = 0
    , start = new Date().valueOf()
    ;

  while (x + 1 != x) {
    if (!(x % 10000000)) {
      console.log(x);
    }

    x += 1
  }

  console.log(x, new Date().valueOf() - start);
}());
32
CoolAJ86

ECMAScript 6:

Number.MAX_SAFE_INTEGER = Math.pow(2, 53)-1;
Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;
28
WaiKit Kung

簡単な答えは「それが依存する」です。

どこでもビット演算子を使用している場合(または配列の長さを参照している場合)、範囲は次のとおりです。

未署名:0…(-1>>>0)

署名済み:(-(-1>>>1)-1)…(-1>>>1)

(そのため、ビット演算子と配列の最大長が32ビット整数に制限されることがあります。)

ビット演算子を使用したり、配列長を操作したりしていない場合は、次の手順を実行します。

署名済み:(-Math.pow(2,53))…(+Math.pow(2,53))

これらの制限は、IEEE 754倍精度浮動小数点表現に一般的に対応する「数値」型の内部表現によって課されます。 (通常の符号付き整数とは異なり、負の制限の大きさは、実際には 負の 0!を含む内部表現の特性により、正の制限の大きさと同じです。)

27
danorton

以前の多くの回答は、9007199254740992 === 9007199254740992 + 1trueの結果を示しています
9 007 199 254 740 991が最大安全整数であることを確認します。

蓄積を続けた場合:

input: 9007199254740992 + 1  output: 9007199254740992  // expected: 9007199254740993
input: 9007199254740992 + 2  output: 9007199254740994  // expected: 9007199254740994
input: 9007199254740992 + 3  output: 9007199254740996  // expected: 9007199254740995
input: 9007199254740992 + 4  output: 9007199254740996  // expected: 9007199254740996

9 007 199 254 740 992より大きい数のうち、偶数だけがrepresentableであることがわかりました。

倍精度64ビットバイナリ形式がこれにどのように機能するかを説明する入り口です。このバイナリ形式を使用して9 007 199 254 740 992がどのように保持(表現)されるかを見てみましょう。

4 503 599 627 370 496から開始し、最初にフォーマットの短いバージョンを使用します。

  1 . 0000 ---- 0000  *  2^52            =>  1  0000 ---- 0000.  
     |-- 52 bits --|    |exponent part|        |-- 52 bits --|

矢印の前にビット値1と隣接する基数点があり、2^52を掛けることで基数点を52ステップ右に移動します。 、そして最後に行きます。現在、バイナリで4503599627370496を取得します。

すべてのビットが1に設定されるまで、この値に1を累積し始めます。これは、10進数で9 007 199 254 740 991に等しくなります。

  1 . 0000 ---- 0000  *  2^52  =>  1  0000 ---- 0000.  
                       (+1)
  1 . 0000 ---- 0001  *  2^52  =>  1  0000 ---- 0001.  
                       (+1)
  1 . 0000 ---- 0010  *  2^52  =>  1  0000 ---- 0010.  
                       (+1)
                        . 
                        .
                        .
  1 . 1111 ---- 1111  *  2^52  =>  1  1111 ---- 1111. 

倍精度64ビットバイナリ形式では、分数に厳密に52ビットが割り当てられているため、1を追加するのに使用できるビットはないため、すべてを設定することができます。ビットを0に戻し、指数部を操作します。

  |--> This bit is implicit and persistent.
  |        
  1 . 1111 ---- 1111  *  2^52      =>  1  1111 ---- 1111. 
     |-- 52 bits --|                     |-- 52 bits --|

                          (+1)
                                     (radix point has no way to go)
  1 . 0000 ---- 0000  *  2^52 * 2  =>  1  0000 ---- 0000. * 2  
     |-- 52 bits --|                     |-- 52 bits --|

  =>  1 . 0000 ---- 0000  *  2^53 
         |-- 52 bits --| 

これで9 007 199 254 740 992が得られ、それより大きな数値では、フォーマットが保持できるのは分数の2倍、これは、小数部の1加算ごとに実際に2加算に等しいことを意味します。そのため、倍精度64ビットバイナリ形式は、数値がより大きい場合、奇数を保持できません。 9 007 199 254 740 992

                            (consume 2^52 to move radix point to the end)
  1 . 0000 ---- 0001  *  2^53  =>  1  0000 ---- 0001.  *  2
     |-- 52 bits --|                 |-- 52 bits --|

そのため、数が9 007 199 254 740 992 * 2 = 18 014 398 509 481 984を超えると、4回の小数のみを保持できます。

input: 18014398509481984 + 1  output: 18014398509481984  // expected: 18014398509481985
input: 18014398509481984 + 2  output: 18014398509481984  // expected: 18014398509481986
input: 18014398509481984 + 3  output: 18014398509481984  // expected: 18014398509481987
input: 18014398509481984 + 4  output: 18014398509481988  // expected: 18014398509481988

[2 251 799 813 685 2484 503 599 627 370 496)?

 1 . 0000 ---- 0001  *  2^51  =>  1 0000 ---- 000.1
     |-- 52 bits --|                |-- 52 bits  --|

基数ポイントの後のビット値1は正確に2 ^ -1です。 (= 1/2、= 0.5)したがって、4 503 599 627 370 496(2 ^ 52)より小さい数の場合、1ビットが利用可能です整数の1/2倍を表します。

input: 4503599627370495.5   output: 4503599627370495.5  
input: 4503599627370495.75  output: 4503599627370495.5  

未満2 251 799 813 685 248(2 ^ 51)

input: 2251799813685246.75   output: 2251799813685246.8  // expected: 2251799813685246.75 
input: 2251799813685246.25   output: 2251799813685246.2  // expected: 2251799813685246.25 
input: 2251799813685246.5    output: 2251799813685246.5

// If the digits exceed 17, JavaScript round it to print it.
//, but the value is held correctly:

input: 2251799813685246.25.toString(2) 
output: "111111111111111111111111111111111111111111111111110.01"
input: 2251799813685246.75.toString(2) 
output: "111111111111111111111111111111111111111111111111110.11"
input: 2251799813685246.78.toString(2)   
output: "111111111111111111111111111111111111111111111111110.11"

exponent partの利用可能な範囲は何ですか?この形式では11ビットが割り当てられます。 Wiki からの完全なフォーマット:(詳細については、こちらをご覧ください)

IEEE 754 Double Floating Point Format.svg

enter image description here

したがって、指数部を2 ^ 52にするには、e = 1075を正確に設定する必要があります。

14
Carr

他の人はすでに一般的な答えを出しているかもしれませんが、私はそれを決定するための迅速な方法を与えることは良い考えだと思いました:

for (var x = 2; x + 1 !== x; x *= 2);
console.log(x);

Chrome 30では、1ミリ秒以内に9007199254740992が表示されます。

それは2のべき乗をテストして、1を加えたときにどれが自分に等しいかを見つけます。

11
Philippe97

ビット演算に使用するものはすべて、0x80000000(-2147483648または-2 ^ 31)と0x7fffffff(2147483647または2 ^ 31 - 1)の間になければなりません。

コンソールには、0x80000000は+ 2147483648に相当しますが、0x80000000および0x80000000は-2147483648に相当します。

7
Scato

試してください:

maxInt = -1 >>> 1

Firefox 3.6では、2 ^ 31 - 1です。

5
Martin Naatz

X-(X + 1)= - 1という公式で簡単なテストをしました。Safari、Opera、Firefoxで動作可能なXの最大値は9e15です。テストに使用したコードは次のとおりです。

javascript: alert(9e15-(9e15+1));
4
Raynet

sources に行きましょう。

説明

MAX_SAFE_INTEGER定数の値は9007199254740991(9,007,199,254,740,991または9兆)です。その理由は、JavaScriptが IEEE 754 で指定されているように、 倍精度浮動小数点フォーマット数 を使用し、-(253 - 1)253 - 1の間の数字しか安全に表現できないためです。

この文脈で安全とは、整数を正確に表現し、それらを正しく比較する機能を指します。たとえば、Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2はtrueと評価されますが、これは数学的には正しくありません。詳細については Number.isSafeInteger() を参照してください。

MAX_SAFE_INTEGERNumber の静的プロパティであるため、作成した Number オブジェクトのプロパティとしてではなく、常にNumber.MAX_SAFE_INTEGERとして使用します。

ブラウザの互換性

enter image description here

1
simhumileco

私はこのように書いています:

var max_int = 0x20000000000000;
var min_int = -0x20000000000000;
(max_int + 1) === 0x20000000000000;  //true
(max_int - 1) < 0x20000000000000;    //true

Int32と同じ

var max_int32 =  0x80000000;
var min_int32 = -0x80000000;
1
jerome

この記事を書いている時点で、JavaScriptは新しいデータ型BigIntを受け取っています。 ステージ3 でのTC39の提案です。 BigIntはChrome 67以降、FireFox 67以降(有効にするにはオプションが必要です)、Opera 54およびNode 10.4.0で利用可能です。それはSafariなどで進行中です...それは "n"接尾辞を持っている数字リテラルを導入して、そして任意の精度を考慮に入れます:

var a = 123456789012345678901012345678901n;

もちろん、そのような数値が(おそらく意図せずに)数値データ型に強制されると、精度は失われます。

1
trincot

Google Chromeの組み込みJavaScriptでは、番号が無限大と呼ばれる前に約2 ^ 1024に移動できます。

1
Tommy
0
Marwen Trabelsi

Number.MAX_VALUE はJavaScriptで表現可能な最大数値を表します。

誰もそうは言っていないようだから、 v8 エンジンでは31 bits番号とそれ以上の番号の振る舞いに違いがある。

32 bitsがあれば、最初のビットを使ってJavaScriptエンジンにそのデータの種類を伝え、残りのビットに実際のデータを含めることができます。それが V8 31 bisnumbersのための小さな最適化として何をするかです(あるいは以前はそうでしたが、私の情報源はかなり時代遅れです)。最後の31 bitsが数値で、最初のビットが数値かオブジェクト参照かをエンジンに伝えます。

ただし、31 bitsより上の数値を使用すると、データは収まりません。数値は64​​ビットの2倍に囲まれ、最適化は行われません。

下のビデオの一番下の行は、

31ビット 符号付き整数として表現できる数値を優先します。

0
Ced

数が2の2乗の53乗のとき。

Math.pow(2, 53)

JavaScriptはそれを大きな整数として認識しています。それからjavascriptはそれらを 'bigint'として保存するので'bigint'==='bigint'との比較は真になります。

Mathオブジェクト自体にそれらの値を保存するためのより安全な方法。

const bigInt1 = Math.pow(2, 55)
const bigInt2 = Math.pow(2, 66)
console.log(bigInt1 === bigInt2) // false
0

Scatoは書いた:

ビット演算に使用するものはすべて、0x80000000(-2147483648または-2 ^ 31)と0x7fffffff(2147483647または2 ^ 31 - 1)の間でなければなりません。

コンソールから0x80000000は+ 2147483648に等しいが、0x80000000と0x80000000は-2147483648に等しいことがわかります。

16進数は符号なしの正の値なので、0x80000000 = 2147483648です。これは数学的に正しいことです。符号付きの値にしたい場合は、右にシフトする必要があります。0x80000000 >> 0 = -2147483648。代わりに1 << 31と書くこともできます。

0
SammieFox

基本的にはJavaScriptは長い間サポートしていません。
そのため、通常の値で32ビット未満を表すことができる場合は、int型のコンテナを使用します。 32ビットを超える整数値の場合は、doubleが使用されます。二重表示では、整数部分は53ビットで、残りは仮数です(浮動小数点情報を保持するため)。
だから、値は2^53 - 1である9007199254740991を使うことができます
あなたは自分のコードで使う値にNumber.MAX_SAFE_INTEGERでアクセスできます

0
Fisherman