Bir sayının hassasiyetini kaybetmeden gidebileceği JavaScript'in en yüksek tamsayı değeri nedir?


951

Bu dil tarafından tanımlanmış mı? Tanımlanmış bir maksimum var mı? Farklı tarayıcılarda farklı mı?



2
big.js ile kullanabileceğiniz en yüksek tam sayı değeri nedir?
George

@George İşte big.js API'sı: mikemcl.github.io/big.js/#dp
simhumileco

Soru mantıklı değil. Bir sayının bir tamsayı değerine "gittiği" ne anlama gelir? JS'de temsil edebileceğiniz en yüksek tamsayının ne olduğunu sormak istiyorsanız, en yüksek (sonlu) Sayının kendisi bir tamsayıdır.
Veky

@DmitriZaitsev Artık harici kütüphanelere (en azından bazı tarayıcılarda) bağımlı olmamız gerekmiyor. 1n << 10000nherhangi bir bağımlılık gerektirmeden (ve bir sınıra yakın bile değil) herhangi bir hassasiyet kaybetmeden gerçekten, gerçekten büyük bir tamsayıdır.
Amadan

Yanıtlar:


868

JavaScript'in iki sayı türü vardır: Numberve BigInt.

En sık kullanılan sayı türü, Number64 bit kayan noktalı IEEE 754 sayıdır.

Bu türün en büyük tam integral değeri Number.MAX_SAFE_INTEGERşöyledir:

  • 2 53 -1 veya
  • +/- 9.007.199.254.740.991 veya
  • dokuz katrilyon yedi trilyon yüz doksan dokuz milyar iki yüz elli dört milyon yedi yüz kırk bin dokuz yüz doksan bir

Bunu perspektife sokmak gerekirse: bir katrilyon bayt bir petabayt (veya bin terabayt).

Bu bağlamda "güvenli" tamsayıları tam olarak temsil etme ve doğru şekilde karşılaştırma yeteneğini ifade eder.

Spec'ten:

Büyüklüğü 2 53'ten büyük olmayan tüm pozitif ve negatif tamsayıların Numbertipte temsil edilebilir olduğuna dikkat edin (aslında, 0 tamsayısının +0 ve -0 olmak üzere iki gösterimi vardır).

Bundan daha büyük tamsayıları güvenle kullanmak için BigInt, üst sınırı olmayan kullanmanız gerekir .

Bitsel işleçlerin ve kaydırma işleçlerinin 32 bit tamsayılarda çalıştığına dikkat edin, bu durumda, maksimum güvenli tamsayı 2 31 -1 veya 2.147.483.647'dir.

const log = console.log
var x = 9007199254740992
var y = -x
log(x == x + 1) // true !
log(y == y - 1) // also true !

// Arithmetic operators work, but bitwise/shifts only operate on int32:
log(x / 2)      // 4503599627370496
log(x >> 1)     // 0
log(x | 1)      // 1


9,007,199,254,740,992 numarasının konusuyla ilgili teknik not: Bu değerin tam bir IEEE-754 temsili vardır ve bu değeri bir değişkenden atayabilir ve okuyabilirsiniz, böylece tamsayılardan küçük veya eşit olan tamsayılar alanında çok dikkatli bir şekilde seçilen uygulamalar için bu değer, bunu maksimum değer olarak değerlendirebilirsiniz.

Genel durumda, bu IEEE-754 değerini yanlış olarak değerlendirmelisiniz, çünkü mantıksal değeri 9,007,199,254,740,992 veya 9,007,199,254,740,993 kodlayıp kodlamadığı belirsizdir.


75
Bu doğru görünüyor, ancak bunun tanımlandığı bir yer var mı, á la C'nin MAX_INT veya Java'nın Integer.MAX_VALUE?
TALlama

48
4294967295 === Math.pow(2,32) - 1;
CoolAJ86

13
Kesin hassasiyeti sağlamak için kullanabileceğimiz en küçük ve en büyük tam sayı nedir?
Pacerier

38
Belki de javascriptte gerçek (int) olmadığını belirtmek gerekir. Her Number örneği (float) veya NaN'dir.
Pancar-Pancar

53
9007199254740992 gerçekten maksimum değer değil, buradaki son bitin zaten sıfır olduğu varsayılıyor ve bu nedenle 1 bit hassasiyet kaybettiniz. Gerçek güvenli sayı 9007199254740991'dir (Number.MAX_SAFE_INTEGER)
Willem D'Haeseleer

461

> = ES6:

Number.MIN_SAFE_INTEGER;
Number.MAX_SAFE_INTEGER;

<= ES5

Gönderen referans :

Number.MAX_VALUE;
Number.MIN_VALUE;


23
Soruyu, yalnızca maksimum Sayı değerini değil, maksimum Tamsayı değerlerini istemek konusunda biraz daha kesin olacak şekilde düzenledim. Karışıklık için üzgünüm, burada.
TALlama

5
Döndürülen sonucun tüm tarayıcılarda eşit olması garanti ediliyor mu?
Pacerier

7
Bunun Number.MIN_VALUEmümkün olan en küçük pozitif sayı olduğuna dikkat edin . En düşük değer (başka bir şeyden daha az) muhtemelen -Number.MAX_VALUE.
Michael Scheper

34
ES6 tanıtıyor Number.MIN_SAFE_INTEGERveNumber.MAX_SAFE_INTEGER
superlukas

2
Öyleyse, bu durumda, güncellenmiş soru için yanlış olduğu için cevabı oylamalıyız mı yoksa Peter Baily'nin cevaplandığı sırada haklı olduğu için mi bırakmalıyız?
rocketsarefast

112

2 53 == 9 007 199 254 740 992'dir. Bunun nedeni Number, 52 bitlik bir mantiste s'nin kayan nokta olarak depolanmasıdır.

Min değeri -2 53'tür .

Bu eğlenceli şeyler oluyor

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

Ayrıca tehlikeli olabilir :)

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
}

Daha fazla okuma: http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html


1
aklı başında bir zaman dilimi içinde döngü için asla sonuna kadar ulaşamaz olsa da, söylemek isteyebilirsinizi += 1000000000
ninjagecko

2
@ninjagecko, MAX_INT 'da başlıyor, böylece son orada. Ayrıca i + = 1000000000 kullanmak artık onu sonsuz bir döngü yapmaz. Dene.
Ted Bigham

@TedBigham: Ah ayy, bu kadar çabuk hazırdı. Beni iki kez düzelttiğiniz için teşekkürler.
ninjagecko

9,007,199,254,740,991 yerine 9.007.199.254.740.992 için Jimmy'nin argüman bakınız burada . Bu benim takibimle birleştiğinde ikna edici görünüyor.
TJ Crowder

60

JavaScript'te adlı bir sayı var Infinity.

Örnekler:

(Infinity>100)
=> true

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

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

Bu konuyla ilgili bazı sorular için yeterli olabilir.


25
Bir şey bana sonsuzluğun bir tamsayı olarak nitelendirilmediğini söylüyor. :)
devios1

7
Ancak min, minimum bir değer ararken bir değişken başlatmak için yeterince iyi .
djjeck

9
UnutmayınInfinity - 1 === Infinity
H.Wolper

2
ayrıca (Infinity <100) => false ve Math.pow (2,1024) === Infinity
Sijav

6
Ayrıca olumsuz Infinity de ele hiçbir şey değer. Yani1 - Infinity === -Infinity
dmccabe

41

Jimmy'nin cevabı doğru olarak sürekli JavaScript tamsayı spektrumunu temsil -9007199254740992 için 9007199254740992 dahil (9007199254740993 üzgün, düşündüğünüzden sen 9007199254740993 vardır, ama yanlış! Şunlardır altında veya içinde Gösteri jsfiddle ).

console.log(9007199254740993);

Ancak buluntular / programlama (diğer ima biri CoolAJ86 daha bu kanıtlıyor cevabı yok onun cevabını 28.56 yıl içinde bitirmek istiyorum;), işte bunun için biraz daha etkili yoludur (kesin konuşmak gerekirse, daha verimlidir yaklaşık 28.559999999968312 yıl :), bir test kemanı ile birlikte :

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


8
@ CoolAJ86: Lol, 15 Mart 2040'ı dört gözle bekliyorum. Rakamlarımız eşleşirse bir parti
vermeliyiz

var x = Math.pow (2,53) -3; (x! = x + 1) x ++; -> 9007199254740991
MickLH

@MickLH: Bu kodla 9007199254740992 alıyorum . Test etmek için hangi JavaScript motorunu kullanıyorsunuz?
Briguy37

Kendi kodunuzla 9007199254740992 olsun, x'in son değerini kullanmadım, ancak paranoyak nedenlerle x ++ 'ın son değerlendirmesini kullanmadım. Google Chrome btw.
MickLH

@MickLH: değerlendirme , artış gerçekleşmeden öncex++ x değerini verir , böylece muhtemelen tutarsızlığı açıklar. İfadenin x'in son değeri ile aynı değeri değerlendirmesini istiyorsanız, ifadeyi olarak değiştirmeniz gerekir . ++x
peterflynn

32

Güvende olmak

var MAX_INT = 4294967295;

muhakeme

Zeki olacağımı ve x + 1 === xdaha pragmatik bir yaklaşımla değeri bulacağımı düşündüm .

Makinem saniyede sadece 10 milyon sayabilir ... bu yüzden 28.56 yıl içinde kesin cevapla geri göndereceğim.

Eğer bu kadar bekleyemezsen, bahse girmeye hazırım

  • Döngülerinizin çoğu 28.56 yıldır
  • 9007199254740992 === Math.pow(2, 53) + 1 yeterince kanıt
  • Bit kaydırma ile ilgili beklenen sorunları önlemek için 4294967295hangisine bağlı kalmalısınızMath.pow(2,32) - 1

Bulgu 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);
}());

4
test etmek için sadece 2 ^ 53 - 2'de başlayamıyor musunuz? (evet, güvende olmak için -3 ile bile denedim: var x = Math.pow (2,53) -3; iken (x! = x + 1) x ++;) -> 9007199254740991
MickLH

Güzel cevap! Dahası, değerin yerleştiğini biliyorum, ama bulgusu için neden ikili aramayı kullanmıyorsunuz?
higuaro

1
Bunun nesi eğlenceli? Ayrıca, @ Briguy37 beni dövdü: stackoverflow.com/a/11639621/151312
CoolAJ86

32 değere dayalı bu 'güvenli' MAX_INT değerinin Tarih değerleri ile karşılaştırılmayacağını unutmayın. 4294967295 çok dün!
Jerry

1
"Güvende olmak için: var MAX_INT = 4294967295;" komik değil. Bitshifting değilseniz, endişelenmeyin (4294967295'ten daha büyük bir int'e ihtiyacınız yoksa, bu durumda muhtemelen bir dize olarak saklamanız ve bir bigint kütüphanesi kullanmanız gerekir).
CoolAJ86

29

Kısa cevap “duruma bağlıdır”.

Herhangi bir yerde bitsel operatörler kullanıyorsanız (veya bir Dizinin uzunluğundan bahsediyorsanız) aralıklar şunlardır:

İmzasız: 0…(-1>>>0)

İmza: (-(-1>>>1)-1)…(-1>>>1)

(Böylece, bitsel operatörler ve bir dizinin maksimum uzunluğu 32 bit tamsayılarla sınırlıdır.)

Bitsel işleçler kullanmıyorsanız veya dizi uzunluklarıyla çalışmıyorsanız:

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

Bu sınırlamalar, genellikle IEEE 754 çift kesinlikli kayar nokta gösterimine karşılık gelen “Sayı” tipinin iç temsili tarafından uygulanır. (Tipik imzalı tam sayıların aksine, negatif sınırın büyüklüğünün, aslında negatif 0 içeren dahili gösterimin özellikleri nedeniyle, pozitif sınırın büyüklüğü ile aynı olduğunu unutmayın .)


Bu, X'i 32 bit tam sayıya veya işaretsiz tam sayıya dönüştürme konusunda yanılmak istediğim cevap. Bunun cevabını onayladın.
Charlie Affumigato

29

ECMAScript 6:

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

1
Bunun tüm tarayıcılar tarafından (henüz) desteklenmediğine dikkat edin ! Bugün iOS (krom bile değil), Safari ve IE bundan hoşlanmıyor.
cregox

5
Lütfen cevabı dikkatle okuyun, ECMAScript 6'daki Number.MAX_SAFE_INTEGER varsayılan uygulamasını kullanmıyoruz,
Math.pow

ECMA 6'da nasıl uygulandığına dair bir referans olduğunu düşündüm! : PI yorumumun hala geçerli olduğunu düşünüyorum. Hepsi bir bağlam meselesi. ;)
cregox

3
MAX_SAFE_INTEGERGeriye doğru çalışarak tüm tarayıcılarda hesaplamak güvenilir midir? Bunun yerine ileriye doğru hareket etmeli misin? Yani, Sayı.MAX_SAFE_INTEGER = 2 * (Math.pow (2, 52) - 1) + 1;
kjv

Math.pow(2, 53)-1güvenli bir operasyon? En büyük güvenli tamsayıdan bir daha büyük gider.
ioquatix

21

Önceki zamanlardan daha fazla cevaplar sonucunu göstermiştir trueait 9007199254740992 === 9007199254740992 + 1olduğunu doğrulamak için 9 007 199 254 740 991 maksimum ve güvenli tam sayıdır.

Ya biriktirmeye devam edersek:

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

9007 199 254 740 992'den büyük sayılar arasında sadece çift sayıların temsil edilebildiğini görebiliriz .

Bu, çift ​​duyarlıklı 64 bit ikili formatın bu konuda nasıl çalıştığını açıklayan bir giriş . Şimdi bu ikili formatı kullanarak 9 007 199 254 740 992'nin nasıl tutulduğunu (temsil edildiğini) görelim .

4 503 599 627 370 496'dan göstermek için kısa bir sürüm kullanma :

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

Okun sol tarafında, bit değeri 1 ve bitişik bir yarıçap noktası var , daha sonra çarparak 2^52, yarıçap noktasını 52 adım sağa hareket ettiriyoruz ve sonuna kadar gidiyor. Şimdi ikilide 4503599627370496 alıyoruz.

Şimdi, tüm bitler 1 olarak ayarlanana kadar 1'i bu değerde biriktirmeye başlıyoruz, bu da ondalık ondalık 9 007 199 254 740 991'e eşittir .

  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. 

Şimdi, çift ​​duyarlıklı 64 bit ikili formatta , kesinlikle kesir için 52 bit ayırdığı için, bir tane daha 1 eklemek için daha fazla bit mevcut değildir, bu yüzden yapabileceğimiz tüm bitleri 0'a geri döndürmek ve üs kısmını manipüle etmek:

  |--> 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 --| 

Şimdi 9 007 199 254 740 992'yi alıyoruz ve sayıdan daha büyük bir sayı ile formatın tutabileceği kesirin 2 katı, şimdi kesir kısmındaki her 1 ekleme aslında 2 toplama anlamına geliyor, bu yüzden çift 6400 bit ikili biçim , sayı 9 007 199254 740 992'den büyük olduğunda tek sayıları tutamaz :

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

Bu nedenle sayı 9007 199 254 740 992 * 2 = 18 014 398 509 481 984'den büyük olduğunda, kesirin sadece 4 katı tutulabilir:

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 251799813685248 , 4 503 599 627 370 496 ) arasındaki sayıya ne dersiniz ?

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

Yarıçap noktasından sonraki bit değeri 1 tam olarak 2 ^ -1'dir. (= 1/2 , = 0,5) Dolayısıyla, 4 503 599 627 370 496'dan (2 ^ 52) küçük bir sayı olduğunda, tamsayının 1/2 katını temsil etmek için bir bit vardır :

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

Az 2 251 799 813 685 248 (^ 51 2)

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"

Ve mevcut üs parçası aralığı nedir? biçim bunun için 11 bit ayırır. Komple biçimi Wiki : (daha fazla detay oraya gitmek için lütfen)

IEEE 754 Çift Kayan Noktalı Format.svg

resim açıklamasını buraya girin

Bu nedenle üs parçasını 2 ^ 52 yapmak için tam olarak e = 1075 ayarlamamız gerekiyor.


13

Diğerleri zaten genel bir cevap vermiş olabilir, ancak bunu belirlemenin hızlı bir yolunu vermenin iyi bir fikir olacağını düşündüm:

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

Bu da bana Chrome 30'da bir milisaniyeden daha kısa sürede 9007199254740992 veriyor.

'1' eklendiğinde kendisine hangisinin eşit olduğunu bulmak için 2'nin gücünü test edecektir.


Uygulamanızı çökertebilir, diye düşündü.
Sapphire_Brick

8

Bitsel işlemler için kullanmak istediğiniz her şey 0x80000000 (-2147483648 veya -2 ^ 31) ile 0x7fffffff (2147483647 veya 2 ^ 31-1) arasında olmalıdır.

Konsol, 0x80000000'in +2147483648'e eşit olduğunu, ancak 0x80000000 ve 0x80000000'in -2147483648'e eşit olduğunu söyleyecektir.


6

Deneyin:

maxInt = -1 >>> 1

Firefox 3.6'da 2 ^ 31-1'dir.


2
@danorton: Ne yaptığınızı anladığınızdan emin değilim. güce yükseltilmiş^ demektir . JavaScript konsolunda, bir XOR değil kaldırdı yapılır,^
kumarharsh

2
Chrome / Firefox konsolunu açın. 5 ^ 2 yazın. İkili olarak, 5 101ve 2'dir 010. Eğer Bit XOR onları elde edersiniz Şimdi eğer 5(101) ^ 2(010) = 7(111) Bunu Okuyunuz karıştı iseniz nedir burada tartışılıyor Math.pow()değil ^operatörü
kumarharsh

3
Yine kafam karıştı. Ben yorumladı ve ne üzerinde downvoted gelmiş yazılı . Eğer Math.pow () kastedilen buysa, o zaman yazılması gereken budur. JavaScript ile ilgili bir soruya yanıt olarak, farklı bir dilin sözdizimini kullanmak uygun değildir. JavaScript'te geçerli olan bir sözdizimi kullanmak, ancak JavaScript'te amaçlanandan farklı bir anlama sahip bir yorum kullanmak daha da uygunsuzdur.
danorton

10
2 ^ 31 İngilizce'de otuz birinci güce iki tanesini nasıl yazdığıdır. Kod bloğunda değil. Birini kullanan birinden şikayet eder misiniz? Bir cevapta, çünkü bu Javascript'te farklı bir anlamı olan bir karakter mi?
5mm 14

3
Hatta biri olsa gerekir yazma 2³¹ değil 2 ^ 31 en klavye düzenleri varsayılan olarak bu karakterleri olmadığı için düz metin olarak onun ortak, bunu yapmak için. En azından bu cevapta ne anlama geldiğini anlamada herhangi bir sorun yaşamadım.
Jocke

6

Yazım anında JavaScript yeni bir veri türü alıyor: BigInt. EcmaScript 2020'ye dahil edilmesi aşama 4'teki bir TC39 önerisidir . Chrome 67+, FireFox 68+, Opera 54 ve Düğüm 10.4.0'da mevcuttur. Safari, et al ... Devam ediyor "n" sonekine sahip sayısal değişmezleri tanıtır ve keyfi hassasiyet sağlar:BigInt

var a = 123456789012345678901012345678901n;

Elbette, böyle bir sayı bir sayı veri türüne zorlandığında (belki de kasıtsız) kesinlik hala kaybolacaktır.

Ve açıkçası, sonlu bellek nedeniyle her zaman hassas sınırlamalar ve gerekli belleği tahsis etmek ve bu kadar büyük sayılar üzerinde aritmetik yapmak için zaman açısından bir maliyet olacaktır.

Örneğin, yüz bin ondalık basamağı olan bir sayının oluşturulması, tamamlanmadan önce belirgin bir gecikme alacaktır:

console.log(BigInt("1".padEnd(100000,"0")) + 1n)

... ama işe yarıyor.


4

Bir formülle basit bir test yaptım, X- (X + 1) = - 1 ve XI'nin Safari, Opera ve Firefox (OS X'te test edilmiş) üzerinde çalışabileceği en büyük değer 9e15. İşte test için kullandığım kod:

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

1
9e15 = 2 ^ 53 olduğuna dikkat edin (@ Jimmy'nin cevabına bakınız).
Kama

6
9e15 = 9000000000000000. 2 ^ 53 = 9007199254740992. Bu nedenle bilgiçlikçi olmak için, 9e15 sadece yaklaşık 2 ^ 53'e eşittir (iki anlamlı basamaklı).
devios1

@chaiguy 9000000000000000Önemli bir rakam var. 9007199254740992'de 15 önemli rakam var.
Royi Namir

@RoyiNamir Burada anlamsız bir argüman başlatmak istemiyorum, ancak 9000000000000000'de 16 önemli basamak var. Sadece 1 istiyorsanız, 9x10 ^ 15 olarak yazılması gerekir.
devios1

1
@chaiguy No. 9000000000000000olduğu gibi - 1SF var. burada 90*10^14yer alır 2. ( sigfigscalculator.appspot.com ) mathsfirst.massey.ac.nz/Algebra/Decimals/SigFig.htm (alt bölüm)
Royi Namir

3

Ben şöyle yazıyorum:

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

Aynı int32 için

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

3

Kaynaklara gidelim

Açıklama

MAX_SAFE_INTEGERSabit bir değere sahiptir 9007199254740991(9,007,199,254,740,991 veya ~ 9 katrilyon). Bu sayının arkasındaki mantık JavaScript kullanmasıdır çift duyarlı kayan noktalı format numaralarını belirtilen IEEE 754 ve ancak güvenle arasındaki sayıları temsil edebilir -(2^53 - 1)ve 2^53 - 1.

Bu bağlamda güvenli, tam sayıları tam olarak temsil etme ve doğru bir şekilde karşılaştırma yeteneğini ifade eder. Örneğin Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2, matematiksel olarak yanlış olan doğru olarak değerlendirilir. Daha fazla bilgi için Number.isSafeInteger () öğesine bakın .

Çünkü MAX_SAFE_INTEGERstatik özelliği olan Number , her zaman olarak kullanabilirsiniz Number.MAX_SAFE_INTEGER, yerine bir özelliği olarak Numarası oluşturduğunuz nesne.

Tarayıcı Uyumluluğu

resim açıklamasını buraya girin




-1

Scato wrotes:

bitsel işlemler için kullanmak istediğiniz her şey 0x80000000 (-2147483648 veya -2 ^ 31) ile 0x7fffffff (2147483647 veya 2 ^ 31-1) arasında olmalıdır.

konsol size 0x80000000 değerinin +2147483648 değerine, ancak 0x80000000 & 0x80000000 değerinin -2147483648 değerine eşit olduğunu söyleyecektir.

Onaltılı Ondalık işaretsiz pozitif değerlerdir, bu nedenle 0x80000000 = 2147483648 - bu matematiksel olarak doğrudur. İşaretli bir değer yapmak istiyorsanız sağa kaydırmanız gerekir: 0x80000000 >> 0 = -2147483648. Bunun yerine 1 << 31 de yazabilirsiniz.


-7

Firefox 3'ün büyük sayılarla bir sorunu yok gibi görünüyor.

1e + 200 * 1e + 100, 1e + 300'e kadar ince hesaplar.

Safari de onunla hiçbir sorun var gibi görünüyor. (Kayıt için, başka biri bunu test etmeye karar verirse bu bir Mac'te.)

Günün bu saatinde beynimi kaybetmediğim sürece, bu 64 bitlik bir tam sayıdan çok daha büyük.


18
64 bit tam sayı değil, 52/53 bit tam sayı kısmı olan 64 bit kayar nokta sayısıdır. bu yüzden 1e300'e kadar işleyebilir, ancak kesin hassasiyetle değil.
Jimmy

4
Jimmy haklı. Bunu tarayıcında veya JS komut satırında dene:100000000000000010 - 1 => 100000000000000020
Ryan

-7

Node.js ve Google Chrome'un her ikisi de 1024 bit kayan nokta değerleri kullanıyor gibi görünüyor:

Number.MAX_VALUE = 1.7976931348623157e+308

1
-1: Temsili maksimum (tam olmayan integral) sayı ~ 2 ^ 1024 olabilir, ancak bu IEEE-754 64 - bit standardından saptıkları anlamına gelmez .
Roy Tinker

2
MAX_INT? Şunu mu demek istediniz: MAX_VALUE
Raul Guiu

3
bu bir kayan nokta değerinin maksimumudur . Bu uzun bir int depolayabileceğiniz anlamına gelmez
phuclv

1
Ya da daha fazlası , doğruluk kaybı olmadan bu kadar uzun bir int'i güvenilir bir şekilde saklayamazsınız . olarak ifade edilir bu noktada üzerindeki değerler parçacıklar aynı şekilde, yaklaşık değerler olmak için. 2^53MAX_SAFE_INT
IMSoP
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.