Enteros JSON: límite de tamaño

81

¿Se especifica en alguna parte qué tan grandes pueden ser los enteros JSON? Supongo que están limitados a ints normales (32 bits), pero no puedo encontrar en ningún lugar que esté escrito. Necesito codificar identificadores que son largos en Java, así que supongo que necesito almacenarlos como cadenas en JSON para no correr el riesgo de desbordamiento.

Ian Dickinson
fuente

Respuestas:

92

Un número JSON no está limitado por la especificación .

Gramática de números JSON

Dado que JSON es un formato abstracto que no está dirigido exclusivamente a JavaScript, el entorno de destino real determina los límites de lo que se puede interpretar.

También vale la pena señalar que no hay "números enteros JSON", son un subconjunto del tipo de datos "Número".

Tomalak
fuente
12
Como cuestión práctica, los números enteros de Javascript están limitados a aproximadamente 2 ^ 53 (no hay números enteros; solo flotantes IEEE). Pero la especificación JSON es bastante clara en cuanto a que los números JSON tienen un tamaño ilimitado.
Nelson
9
Aunque la respuesta sigue siendo técnicamente correcta, valdría la pena actualizarla, ya que RFC 7159 ayuda a aclarar qué rango de enteros debe considerarse interoperable. (es decir [-(2**53)+1, (2**53)-1].) Si está trabajando fuera de ese rango, utilice enteros codificados en cadena o espere que las implementaciones pierdan precisión.
Tom Christie
@TomChristie La especificación JSON no menciona RFC7159.
Tomalak
3
@Tomalak - Claro - RFC7159 apareció más tarde (2014). Aclara algunas de las inconsistencias / casos extremos que existían previamente, etc. (como la falta de mención sobre rangos numéricos viables)
Tom Christie
2
Hm, después de leer el RFC en detalle, todavía no limita los números. Simplemente insinúa que muchos sistemas usan IEEE754 internamente y que este hecho puede poner limitaciones prácticas en lo que puede ser interpretado por el receptor, que es lo que decía la respuesta desde el principio.
Tomalak
18

RFC 7159: Formato de intercambio de datos de notación de objetos JavaScript (JSON)

Esta especificación permite que las implementaciones establezcan límites en el rango y la precisión de los números aceptados. Dado que el software que implementa IEEE 754-2008 binary64 (doble precisión) números [IEEE754] está generalmente disponible y se usa ampliamente, se puede lograr una buena interoperabilidad mediante implementaciones que no esperan más precisión o rango que el que proporcionan, en el sentido de que las implementaciones se aproximarán a JSON números dentro de la precisión esperada. Un número JSON como 1E400 o 3.141592653589793238462643383279 puede indicar posibles problemas de interoperabilidad, ya que sugiere que el software que lo creó espera que el software receptor tenga mayores capacidades de magnitud numérica y precisión de las que están ampliamente disponibles.

Nolan
fuente
"ampliamente disponible" es un lenguaje vago, en mi opinión. Mientras tanto, algunas implementaciones (como el jsonmódulo estándar de Python ) analizan enteros arbitrarios, incluso más allá de 64 bits (bignums integrados).
Tomasz Gandor
8

Acabo de hacer la siguiente prueba empírica usando la consola de Chrome (v.23 en Mac):

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

> j[0]
1e+228

Si JSON se pasa a través de HTTP, el número se convertirá en String desde Java en cualquier caso y entonces el problema podría estar solo en Javascript.

De la Especificación del lenguaje ECMAScript 4.3.19 :

4.3.19 Valor numérico

valor primitivo correspondiente a un valor IEEE 754 de formato binario de 64 bits de doble precisión

NOTA Un valor de Número es un miembro del tipo Número y es una representación directa de un número.

Que es lo que se define en wikipedia en formato de punto flotante de precisión doble .

Tony Rad
fuente
2
Gracias. Esta estructura JSON en particular está siendo distribuida por el servicio web de back-end en Java, por lo que, siguiendo la respuesta de @ Tomalak, supongo que necesito verificar qué está haciendo realmente mi biblioteca JSON del lado del servidor.
Ian Dickinson
3
Y, para que conste, Jackson analiza correctamente los enteros largos en la entrada JSON en los largos de Java.
Ian Dickinson
Y también para el registro, Jackson emite Java longs correctamente, pero al menos los navegadores basados ​​en Chrome establecen los últimos 3 decimales en cero, es decir, la longitud del número es correcta, pero los últimos 3 decimales siempre se leen 000
Johannes Jander