JSON-Ganzzahlen: Größenbeschränkung

81

Wird irgendwo angegeben, wie groß JSON-Ganzzahlen sein können? Ich vermute, dass sie auf normale (32-Bit) Ints beschränkt sind, aber ich kann nirgendwo etwas finden, das aufgeschrieben ist. Ich muss Bezeichner codieren, die in Java lang sind, daher muss ich diese vermutlich als Zeichenfolgen in JSON speichern, um keinen Überlauf zu riskieren.

Ian Dickinson
quelle

Antworten:

92

Eine JSON-Nummer ist nicht durch die Spezifikation beschränkt .

JSON-Zahlengrammatik

Da JSON ein abstraktes Format ist, das nicht ausschließlich auf JavaScript ausgerichtet ist, bestimmt die tatsächliche Zielumgebung die Grenzen dessen, was interpretiert werden kann.

Es ist auch erwähnenswert, dass es keine "JSON-Ganzzahlen" gibt, sondern eine Teilmenge des Datentyps "Number".

Tomalak
quelle
12
In der Praxis sind Javascript-Ganzzahlen auf etwa 2 ^ 53 begrenzt (es gibt keine Ganzzahlen; nur IEEE-Floats). Die JSON-Spezifikation ist jedoch ziemlich klar, dass JSON-Nummern eine unbegrenzte Größe haben.
Nelson
9
Obwohl die Antwort technisch korrekt bleibt, lohnt es sich, sie zu aktualisieren, da RFC 7159 dabei hilft, zu klären, welcher Bereich von Ganzzahlen als interoperabel angesehen werden sollte. (dh [-(2**53)+1, (2**53)-1]) Wenn Sie außerhalb dieses Bereichs arbeiten, verwenden Sie entweder stringcodierte Ganzzahlen oder erwarten Sie, dass Implementierungen an Genauigkeit verlieren.
Tom Christie
@ TomChristie In der JSON-Spezifikation wird RFC7159 nicht erwähnt.
Tomalak
3
@Tomalak - Sicher - RFC7159 kam später (2014). Klärt einige der zuvor vorhandenen Inkonsistenzen / Randfälle usw. (z. B. das Fehlen jeglicher Erwähnung funktionsfähiger numerischer Bereiche)
Tom Christie
2
Hm, beim detaillierten Lesen des RFC sind die Zahlen immer noch nicht begrenzt. Es wird lediglich darauf hingewiesen, dass viele Systeme IEEE754 intern verwenden und dass diese Tatsache die Interpretation durch den Empfänger praktisch einschränken kann, wie in der Antwort die ganze Zeit angegeben.
Tomalak
18

RFC 7159: Das JSON-Datenaustauschformat (JavaScript Object Notation)

Diese Spezifikation ermöglicht es Implementierungen, Grenzen für den Bereich und die Genauigkeit der akzeptierten Zahlen festzulegen. Da Software, die IEEE 754-2008-Binär-64-Zahlen (doppelte Genauigkeit) [IEEE754] implementiert, allgemein verfügbar und weit verbreitet ist, kann eine gute Interoperabilität durch Implementierungen erreicht werden, die nicht mehr Präzision oder Reichweite erwarten als diese, in dem Sinne, dass Implementierungen sich JSON annähern Zahlen innerhalb der erwarteten Genauigkeit. Eine JSON-Nummer wie 1E400 oder 3.141592653589793238462643383279 kann auf potenzielle Interoperabilitätsprobleme hinweisen, da dies darauf hindeutet, dass die von ihr erstellte Software erwartet, dass empfangende Software über größere Funktionen für numerische Größe und Genauigkeit verfügt, als allgemein verfügbar ist.

Nolan
quelle
"weit verbreitet" ist eine vage Sprache, IMO. In der Zwischenzeit jsonanalysieren einige Implementierungen (wie das Standardmodul von Python ) beliebige Ganzzahlen, sogar über 64 Bit hinaus (integrierte Bignums).
Tomasz Gandor
8

Ich habe gerade den folgenden empirischen Test mit der Chrome-Konsole (v.23 auf Mac) durchgeführt:

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

> j[0]
1e+228

Wenn JSON über HTTP übergeben wird, wird die Nummer in jedem Fall von Java in String konvertiert, und das Problem kann nur in Javascript auftreten.

Aus der ECMAScript-Sprachspezifikation 4.3.19 :

4.3.19 Zahlenwert

primitiver Wert, der einem IEEE 754-Wert im 64-Bit-Binärformat mit doppelter Genauigkeit entspricht

HINWEIS Ein Zahlenwert ist ein Mitglied des Zahlentyps und eine direkte Darstellung einer Zahl.

Welches ist, was in Wikipedia Gleitkomma-Format mit doppelter Genauigkeit definiert .

Tony Rad
quelle
2
Vielen Dank. Diese spezielle JSON-Struktur wird vom Back-End-Webdienst in Java ausgegeben. Nach der Antwort von @ Tomalak muss ich also überprüfen, was meine serverseitige JSON-Bibliothek tatsächlich tut.
Ian Dickinson
3
Und für den Datensatz analysiert Jackson lange Ganzzahlen in JSON-Eingaben korrekt in Java-Longs.
Ian Dickinson
Und auch für die Aufzeichnung, Jackson gibt Java-Longs korrekt aus, aber zumindest Chrome-basierte Browser setzen die letzten 3 Dezimalstellen auf Null, dh die Länge der Zahl ist korrekt, aber die letzten 3 Dezimalstellen lauten immer 000
Johannes Jander