Czy to określa język? Czy istnieje określone maksimum? Czy różni się w różnych przeglądarkach?
javascript
math
browser
cross-browser
TALlama
źródło
źródło
1n << 10000n
jest naprawdę dużą liczbą całkowitą, bez utraty precyzji, bez żadnych zależności (i nie trzeba dodawać, nawet bliskie granicy).Odpowiedzi:
JavaScript ma dwa typy liczb:
Number
iBigInt
.Najczęściej stosowanym typem liczby
Number
jest 64-bitowa liczba zmiennoprzecinkowa IEEE 754 .Największa dokładna całkowita wartość tego typu
Number.MAX_SAFE_INTEGER
to:Mówiąc inaczej: jeden kwadrylion bajtów to petabajt (lub tysiąc terabajtów).
„Bezpieczny” w tym kontekście odnosi się do możliwości dokładnego przedstawienia liczb całkowitych i ich prawidłowego porównania.
Ze specyfikacji:
Aby bezpiecznie używać liczb całkowitych większych niż to, musisz użyć
BigInt
, który nie ma górnej granicy.Zauważ, że operatory bitowe i operatory shift działają na 32-bitowych liczbach całkowitych, więc w takim przypadku maksymalna bezpieczna liczba całkowita wynosi 2 31 -1 lub 2 147 483 647.
Uwaga techniczna na temat liczby 9 007,199,254,740,992: Istnieje dokładna reprezentacja tej wartości według IEEE-754, i możesz przypisać i odczytać tę wartość ze zmiennej, więc dla bardzo starannie wybranych aplikacji w dziedzinie liczb całkowitych mniejszych lub równych tę wartość można traktować jako wartość maksymalną.
W ogólnym przypadku należy traktować tę wartość IEEE-754 jako niedokładną, ponieważ nie jest jednoznaczne, czy koduje ona wartość logiczną 9,007,199,254,740,992, czy 9 007,199,25 940,993.
źródło
4294967295 === Math.pow(2,32) - 1;
> = ES6:
<= ES5
Z referencji :
Pokaż fragment kodu
źródło
Number.MIN_VALUE
jest to najmniejsza możliwa liczba dodatnia . Prawdopodobnie jest to najmniejsza wartość (tj. Mniejsza niż cokolwiek innego)-Number.MAX_VALUE
.Number.MIN_SAFE_INTEGER
iNumber.MAX_SAFE_INTEGER
Wynosi 2 53 == 9 007 199 254 740 992. Jest tak, ponieważ
Number
s są przechowywane jako zmiennoprzecinkowe w 52-bitowej mantysie.Minimalna wartość to -2 53 .
To sprawia, że dzieją się fajne rzeczy
I może być również niebezpieczne :)
Dalsza lektura: http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html
źródło
i += 1000000000
W JavaScript istnieje pewna liczba o nazwie
Infinity
.Przykłady:
Może to wystarczyć w przypadku niektórych pytań dotyczących tego tematu.
źródło
min
zmienną, gdy szukasz wartości minimalnej.Infinity - 1 === Infinity
1 - Infinity === -Infinity
Odpowiedź Jimmy'ego poprawnie reprezentuje ciągłe spektrum JavaScript jako -9007199254740992 do 9007199254740992 włącznie (przepraszam 9007199254740993, możesz pomyśleć, że masz 9007199254740993, ale się mylisz! Demonstracja poniżej lub w jsfiddle ).
Jednak nie ma odpowiedzi, która znalazłaby / udowodniłaby to programowo (inna niż ta, o której wspominał CoolAJ86 w swojej odpowiedzi , która skończyłaby się za 28,56 lat;), więc oto nieco bardziej skuteczny sposób na to (dokładniej mówiąc, jest bardziej wydajny o około 28,559999999968312 lat :), wraz ze skrzypką testową :
źródło
x++
daje wartość x przed wystąpieniem przyrostu, więc prawdopodobnie wyjaśnia to rozbieżność. Jeśli chcesz, aby wyrażenie miało taką samą wartość jak końcowa wartość x, powinieneś to zmienić na++x
.Być bezpiecznym
Rozumowanie
Myślałem, że będę sprytny i znajdę wartość, za jaką
x + 1 === x
przyniesie bardziej pragmatyczne podejście.Moja maszyna może liczyć tylko około 10 milionów na sekundę ... więc odpowiem z ostateczną odpowiedzią za 28,56 lat.
Jeśli nie możesz czekać tak długo, jestem gotów się założyć
9007199254740992 === Math.pow(2, 53) + 1
jest wystarczającym dowodem4294967295
tego,Math.pow(2,32) - 1
aby uniknąć oczekiwanych problemów z przesuwaniem bitówZnalezienie
x + 1 === x
:źródło
Krótka odpowiedź brzmi „to zależy”.
Jeśli używasz operatorów bitowych w dowolnym miejscu (lub jeśli odwołujesz się do długości tablicy), zakresy są następujące:
Bez podpisu:
0…(-1>>>0)
Podpisano:
(-(-1>>>1)-1)…(-1>>>1)
(Zdarza się, że operatory bitowe i maksymalna długość tablicy są ograniczone do 32-bitowych liczb całkowitych.)
Jeśli nie używasz operatorów bitowych lub pracujesz z długością tablicy:
Podpisano:
(-Math.pow(2,53))…(+Math.pow(2,53))
Ograniczenia te są narzucone przez wewnętrzną reprezentację typu „Liczba”, która zasadniczo odpowiada reprezentacji zmiennoprzecinkowej podwójnej precyzji IEEE 754. (Należy zauważyć, że w przeciwieństwie do typowych liczb całkowitych ze znakiem, wielkość limitu ujemnego jest taka sama jak wielkość limitu dodatniego, ze względu na cechy reprezentacji wewnętrznej, która w rzeczywistości zawiera ujemną wartość 0!)
źródło
ECMAScript 6:
źródło
MAX_SAFE_INTEGER
we wszystkich przeglądarkach jest niezawodne, jeśli pracujesz wstecz? Czy zamiast tego powinieneś iść do przodu? Tj. Number.MAX_SAFE_INTEGER = 2 * (Math.pow (2, 52) - 1) + 1;Math.pow(2, 53)-1
bezpieczna jest operacja? Jest większa niż największa bezpieczna liczba całkowita.Wiele odpowiedzi od wcześniej wykazały wynik
true
w9007199254740992 === 9007199254740992 + 1
celu sprawdzenia, 9 007 199 254 740 991 to maksymalna liczba całkowita i bezpieczna.Co się stanie, jeśli będziemy kontynuować gromadzenie:
Możemy dowiedzieć się, że wśród liczb większych niż 9 007 199 254 740 992 tylko liczby parzyste są reprezentowalne .
Jest to wejście, aby wyjaśnić, w jaki sposób działa na tym 64-bitowy format podwójnej precyzji . Zobaczmy, jak 9 007 199 254 740 992 może być przechowywany (reprezentowany) przy użyciu tego formatu binarnego.
Używanie krótkiej wersji, aby to zademonstrować 4 503 599 627 370 496 :
Po lewej stronie strzałki mamy wartość bitu 1 i sąsiedni punkt podstawy , a następnie pomnożąc
2^52
, przesuwamy punkt podstawy o 52 kroki i idzie do końca. Teraz otrzymujemy 4503599627370496 w postaci binarnej.Teraz zaczynamy kumulować 1 do tej wartości, aż wszystkie bity zostaną ustawione na 1, co jest równe 9 007 199 254 740 991 dziesiętnie.
Teraz, ponieważ to w 64-bitowym formacie binarnym o podwójnej precyzji przydziela ułamek 52 bitów, ułamek nie jest już dostępny do dodania 1, więc możemy ustawić wszystkie bity z powrotem na 0 i manipuluj częścią wykładniczą:
Teraz otrzymujemy 9 007 199 254 740 992 , a przy większej liczbie format może pomieścić 2 razy część ułamka , co oznacza, że teraz 1 dodanie części ułamkowej faktycznie równa się 2 dodatkom, dlatego podwójne -precision 64-bitowy format binarny nie może przechowywać liczb nieparzystych, gdy liczba jest większa niż 9 007 199 254 740 992 :
Tak więc, gdy liczba osiągnie więcej niż 9 007 199 254 740 992 * 2 = 18 014 398 509 481 984, tylko 4 razy ułamek może być utrzymany:
Co powiesz na liczbę między [ 2 251 799 813 685 248 , 4 503 599 627 370 496 )?
Wartość bitu 1 po punkcie radix wynosi dokładnie 2 ^ -1. (= 1/2, = 0,5) Więc jeśli liczba jest mniejsza niż 4 503 599 627 370 496 (2 ^ 52), dostępny jest jeden bit reprezentujący 1/2 razy liczby całkowitej :
Mniej niż 2 251 799 813 685 248 (2 ^ 51)
Jaki jest dostępny zakres części wykładniczej ? format przydziela mu 11 bitów. Pełny format z Wiki : (Aby uzyskać więcej informacji, przejdź tam)
Aby więc część wykładnicza wynosiła 2 ^ 52, musimy dokładnie ustawić e = 1075.
źródło
Inni mogli już udzielić ogólnej odpowiedzi, ale pomyślałem, że dobrym pomysłem byłoby podanie szybkiego sposobu jej ustalenia:
Co daje mi 9007199254740992 w mniej niż milisekundę w Chrome 30.
Testuje moc 2, aby znaleźć, która z „dodanych” 1 równa się sobie.
źródło
Wszystko, czego chcesz użyć do operacji bitowych, musi znajdować się między 0x80000000 (-2147483648 lub -2 ^ 31) a 0x7fffffff (2147483647 lub 2 ^ 31-1).
Konsola powie ci, że 0x80000000 równa się +2147483648, ale 0x80000000 i 0x80000000 wynosi -2147483648.
źródło
Próbować:
W Firefoksie 3.6 jest to 2 ^ 31 - 1.
źródło
^
oznacza podniesione do władzy . W konsoli javascript^
jest XOR , nie podniesiony do101
a 2 to010
. Teraz, jeśli bitorujesz je XOR, otrzymasz5(101) ^ 2(010) = 7(111)
CZYTAJ TO, JEŚLI JESTEŚ ZAUFANY To, o czym tutaj dyskutujemy,Math.pow()
nie jest^
operatoremW momencie pisania, JavaScript odbiera nowy typ danych:
BigInt
. Jest to propozycja TC39 na etapie 4, która ma zostać uwzględniona w EcmaScript 2020 .BigInt
jest dostępny w Chrome 67+, FireFox 68+, Opera 54 i Node 10.4.0. Jest w toku w Safari i in. ... Wprowadza literały liczbowe z sufiksem „n” i pozwala na dowolną precyzję:Precyzja nadal będzie oczywiście utracona, gdy taka liczba zostanie (być może nieumyślnie) wymuszona na typ danych liczbowych.
I oczywiście zawsze będą istnieć ograniczenia precyzji ze względu na skończoną pamięć i koszt pod względem czasu, aby przydzielić niezbędną pamięć i wykonać arytmetykę na tak dużych liczbach.
Na przykład generowanie liczby o stu tysiącach cyfr dziesiętnych zajmie zauważalne opóźnienie przed ukończeniem:
... ale to działa.
źródło
Zrobiłem prosty test z formułą, X- (X + 1) = - 1, a największa wartość XI, jaką można uzyskać w przeglądarce Safari, Opera i Firefox (testowana w systemie OS X), to 9e15. Oto kod, którego użyłem do testowania:
źródło
9000000000000000
Jest 1 znacząca liczba. w `9007199254740992` jest 15 znaczących liczb.9000000000000000
jak jest - ma1
SF. gdzie90*10^14
ma 2. ( sigfigscalculator.appspot.com ) i mathsfirst.massey.ac.nz/Algebra/Decimals/SigFig.htm (dolna część)Piszę tak:
To samo dla int32
źródło
Przejdźmy do źródeł
Opis
Kompatybilność z przeglądarkami
źródło
We wbudowanym javascript w Google Chrome możesz przejść do około 2 ^ 1024, zanim numer nazywa się nieskończonością.
źródło
W JavaScript reprezentacja liczb to
2^53 - 1
.Jednakże ,
Bitwise operation
są obliczane32 bits ( 4 bytes )
, czyli jeśli przekroczy 32-bitowego przesunięcia zaczniesz utraty bitów.źródło
Wato Scato:
Szesnastkowe są dodatnimi wartościami bez znaku, więc 0x80000000 = 2147483648 - to matematycznie poprawne. Jeśli chcesz, aby była to podpisana wartość, musisz przesunąć w prawo: 0x80000000 >> 0 = -2147483648. Możesz też napisać 1 << 31.
źródło
Firefox 3 nie wydaje się mieć problemu z dużymi liczbami.
1e + 200 * 1e + 100 obliczy grzywnę do 1e + 300.
Wygląda na to, że Safari również nie ma z tym problemu. (Dla przypomnienia, jest to na komputerze Mac, jeśli ktoś zdecyduje się to przetestować).
O ile nie straciłem mózgu o tej porze dnia, jest to znacznie więcej niż 64-bitowa liczba całkowita.
źródło
100000000000000010 - 1 => 100000000000000020
Wydaje się, że Node.js i Google Chrome używają 1024-bitowych wartości zmiennoprzecinkowych, więc:
źródło
2^53
określa się jako,MAX_SAFE_INT
ponieważ powyżej tego punktu wartości stają się przybliżeniami, podobnie jak ułamki.