Pertanyaan Apa nilai bilangan bulat tertinggi JavaScript yang dapat disimpan nomor tanpa kehilangan presisi?


Apakah ini didefinisikan oleh bahasa? Apakah ada batasan yang ditentukan? Apakah itu berbeda di browser yang berbeda?


798
2017-11-20 22:47


asal


Jawaban:


+/- 9007199254740991

ECMA Bagian 8.5 - Angka

Perhatikan bahwa semua bilangan bulat positif dan negatif yang besarnya tidak lebih dari 253 dapat diwakili dalam jenis Nomor (memang, bilangan bulat 0 memiliki dua representasi, +0 dan −0).

Mereka adalah nilai-nilai titik mengambang 64-bit, nilai integral mutlak terbesar adalah 253-1, atau 9007199254740991. Dalam ES6, ini didefinisikan sebagai Number.MAX_SAFE_INTEGER.

Perhatikan bahwa operator bitwise dan operator shift beroperasi pada ints 32-bit, sehingga dalam kasus itu, bilangan bulat aman maksimal adalah 231-1, atau 2147483647.


Uji coba!

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

727
2017-11-20 22:53



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

<= ES5

Dari referensi: 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


404
2017-11-20 22:52



Ini 253 == 9 007 199 254 740 992. Ini karena Numbers disimpan sebagai floating-point dalam 52-bit mantissa.

Nilai min adalah -253.

Ini membuat beberapa hal menyenangkan terjadi

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

Dan bisa juga berbahaya :)

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
}

Bacaan lebih lanjut: http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html


101
2017-12-07 10:40



Di JavaScript, ada nomor yang disebut Infinity.

Contoh:

(Infinity>100)
=> true

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

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

Ini mungkin cukup untuk beberapa pertanyaan mengenai topik ini.


53
2018-01-20 21:42



Jawaban Jimmy benar mewakili spektrum integer JavaScript kontinyu sebagai -9007199254740992 untuk 9007199254740992 inklusif (maaf 9007199254740993, Anda mungkin berpikir Anda adalah 9007199254740993, tetapi Anda salah!   Demonstrasi di bawah atau di jsfiddle).

document.write(9007199254740993);

Namun, tidak ada jawaban yang menemukan / membuktikan ini secara programatik (selain yang dimaksud oleh CoolAJ86 jawabannya yang akan selesai dalam 28,56 tahun;), jadi inilah cara yang sedikit lebih efisien untuk melakukannya (tepatnya, itu lebih efisien sekitar 28,559999999968312 tahun :), bersama dengan tes biola:

/**
 * 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);


37
2017-07-24 21:30



Supaya aman

var MAX_INT = 4294967295;

Pemikiran

Saya pikir saya akan pintar dan menemukan nilainya x + 1 === x dengan pendekatan yang lebih pragmatis.

Mesin saya hanya dapat menghitung 10 juta per detik atau lebih ... jadi saya akan posting kembali dengan jawaban pasti dalam 28,56 tahun.

Jika Anda tidak bisa menunggu selama itu, saya berani bertaruh itu

  • Sebagian besar loop Anda tidak berjalan selama 28,56 tahun
  • 9007199254740992 === Math.pow(2, 53) + 1 cukup bukti
  • Anda harus tetap 4294967295 yang mana Math.pow(2,32) - 1 untuk menghindari masalah yang diharapkan dengan sedikit pergeseran

Temuan 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
2017-08-24 17:29



ECMAScript 6:

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

28
2018-03-31 05:52



Jawaban singkatnya adalah "tergantung."

Jika Anda menggunakan operator bitwise di mana saja (atau jika Anda mengacu pada panjang Array), rentangnya adalah:

Tidak ditandatangani: 0…(-1>>>0)

Tertanda: (-(-1>>>1)-1)…(-1>>>1)

(Kebetulan bahwa operator bitwise dan panjang maksimum array terbatas pada bilangan bulat 32-bit.)

Jika Anda tidak menggunakan operator bitwise atau bekerja dengan panjang larik:

Tertanda: (-Math.pow(2,53))…(+Math.pow(2,53))

Batasan ini ditentukan oleh representasi internal dari jenis "Angka", yang umumnya sesuai dengan representasi floating-point presisi-ganda IEEE 754. (Perhatikan bahwa tidak seperti bilangan bulat bertanda khas, besarnya batas negatif sama dengan besarnya batas positif, karena karakteristik representasi internal, yang sebenarnya mencakup negatif 0!)


27
2017-07-17 07:13



Yang lain mungkin telah memberikan jawaban yang umum, tetapi saya pikir itu akan menjadi ide yang baik untuk memberikan cara cepat untuk menentukannya:

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

Yang memberi saya 9007199254740992 dalam waktu kurang dari satu milidetik di Chrome 30.

Ini akan menguji kekuatan 2 untuk menemukan yang mana, ketika 'ditambahkan' 1, sama dengan dirinya.


11
2017-10-05 16:53