Liczby całkowite JSON: ograniczenie rozmiaru

81

Czy gdziekolwiek określono, jak duże mogą być liczby całkowite JSON? Domyślam się, że są ograniczone do normalnych (32-bitowych) int, ale nie mogę znaleźć nigdzie, co zostało zapisane. Muszę zakodować identyfikatory, które są długie w Javie, więc zakładam, że muszę je przechowywać jako ciągi w JSON, aby nie ryzykować przepełnienia.

Ian Dickinson
źródło

Odpowiedzi:

93

Numer JSON nie jest ograniczony specyfikacją .

Gramatyka liczb JSON

Ponieważ JSON to abstrakcyjny format, który nie jest przeznaczony wyłącznie dla języka JavaScript, rzeczywiste środowisko docelowe określa granice tego, co można interpretować.

Warto również zauważyć, że nie ma „liczb całkowitych JSON”, są one podzbiorem typu danych „Number”.

Tomalak
źródło
12
W praktyce liczby całkowite w Javascript są ograniczone do około 2 ^ 53 (nie ma liczb całkowitych; tylko zmiennoprzecinkowe IEEE). Ale specyfikacja JSON jest całkiem jasna, że ​​numery JSON mają nieograniczony rozmiar.
Nelson,
10
Chociaż odpowiedź jest technicznie poprawna, warto ją zaktualizować, ponieważ RFC 7159 pomaga wyjaśnić, jaki zakres liczb całkowitych należy uznać za interoperacyjny. (tj [-(2**53)+1, (2**53)-1].) Jeśli pracujesz poza tym zakresem, użyj liczb całkowitych zakodowanych jako łańcuch znaków lub spodziewaj się, że implementacje stracą precyzję.
Tom Christie
@TomChristie Specyfikacja JSON nie wspomina o RFC7159.
Tomalak
4
@Tomalak - Sure - RFC7159 pojawił się później (2014). Wyjaśnia niektóre z wcześniej istniejących niespójności / skrajnych przypadków itp. (Takich jak brak jakiejkolwiek wzmianki o działających zakresach liczbowych)
Tom Christie,
2
Hm, po szczegółowym przeczytaniu RFC nadal nie ogranicza liczby. Wskazuje tylko, że wiele systemów używa wewnętrznie IEEE754 i że fakt ten może nakładać praktyczne ograniczenia na to, co może zinterpretować odbiornik, co jest odpowiedzią na cały czas.
Tomalak
18

RFC 7159: format wymiany danych JavaScript Object Notation (JSON)

Ta specyfikacja pozwala implementacjom ustawić limity zakresu i precyzji akceptowanych liczb. Ponieważ oprogramowanie, które implementuje liczby binary64 (podwójnej precyzji) IEEE 754-2008 [IEEE754], jest ogólnie dostępne i szeroko stosowane, dobrą interoperacyjność można osiągnąć dzięki implementacjom, które nie oczekują większej precyzji ani zakresu niż te, w tym sensie, że implementacje będą zbliżone do formatu JSON liczby z oczekiwaną dokładnością. Numer JSON, taki jak 1E400 lub 3.141592653589793238462643383279, może wskazywać na potencjalne problemy ze współdziałaniem, ponieważ sugeruje, że oprogramowanie, które je utworzyło, spodziewa się, że otrzyma oprogramowanie będzie miało większe możliwości w zakresie wielkości liczbowej i precyzji niż jest to powszechnie dostępne.

Nolan
źródło
„powszechnie dostępne” to niejasny język, IMO. W międzyczasie niektóre implementacje (takie jak standardowy jsonmoduł Pythona ) analizują dowolne liczby całkowite, nawet powyżej 64 bitów (wbudowane bignum).
Tomasz Gandor
„szeroko dostępny” nie jest tak niejasny, kiedy wcześniej stwierdzono, że IEEE754 jest „szeroko stosowany”.
Jason Warner
8

Właśnie wykonałem następujący test empiryczny przy użyciu konsoli Chrome (wersja 23 na Macu):

> var j = JSON.parse("[999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999]")
undefined

> j[0]
1e+228

Jeśli JSON jest przesyłany przez HTTP, w każdym przypadku liczba zostanie przekonwertowana na ciąg znaków z języka Java, a problem może dotyczyć tylko JavaScript.

Ze specyfikacji języka ECMAScript 4.3.19 :

4.3.19 Wartość liczbowa

wartość pierwotna odpowiadająca wartości podwójnej precyzji w 64-bitowym formacie binarnym IEEE 754

UWAGA Wartość Number należy do typu Number i jest bezpośrednią reprezentacją liczby.

To właśnie zdefiniowano w Wikipedii w formacie zmiennoprzecinkowym podwójnej precyzji .

Tony Rad
źródło
2
Dzięki. Ta konkretna struktura JSON jest udostępniana przez usługę sieciową zaplecza w Javie, więc podążając za odpowiedzią @ Tomalak, myślę, że muszę sprawdzić, co tak naprawdę robi moja biblioteka JSON po stronie serwera.
Ian Dickinson
3
I dla przypomnienia, Jackson analizuje długie liczby całkowite z danych wejściowych JSON poprawnie w długościach Java.
Ian Dickinson
Dla przypomnienia, Jackson poprawnie emituje długie znaki w Javie, ale przynajmniej przeglądarki oparte na Chrome ustawiają ostatnie 3 cyfry po przecinku na zero, tj. Długość liczby jest poprawna, ale ostatnie 3 cyfry po przecinku zawsze oznaczają 000
Johannes Jander