tutorial - récupérer données json javascript




Quelle est la méthode acceptée pour envoyer des valeurs 64 bits sur JSON? (4)

Certaines de mes données sont des entiers 64 bits. Je voudrais les envoyer à un programme JavaScript fonctionnant sur une page.

Cependant, autant que je sache, les entiers dans la plupart des implémentations JavaScript sont des quantités signées 32 bits.

Mes deux options semblent être:

  1. Envoyer les valeurs sous forme de chaînes
  2. Envoyer les valeurs sous forme de nombres à virgule flottante 64 bits

L'option (1) n'est pas parfaite, mais l'option (2) semble beaucoup moins parfaite (perte de données).

Comment avez-vous géré cette situation?


Cela semble être moins un problème avec JSON et plus un problème avec Javascript lui-même. Que comptez-vous faire avec ces chiffres? Si c'est juste un jeton magique que vous devez renvoyer au site Web plus tard, utilisez simplement une chaîne contenant la valeur. Si vous avez réellement besoin de faire de l'arithmétique sur la valeur, vous pouvez éventuellement écrire vos propres routines Javascript pour l'arithmétique 64 bits.

Une façon de représenter les valeurs en Javascript (et donc en JSON) serait de diviser les nombres en deux valeurs de 32 bits, par exemple.

  [ 12345678, 12345678 ]

Pour diviser une valeur 64 bits en deux valeurs 32 bits, procédez comme suit:

  output_values[0] = (input_value >> 32) & 0xffffffff;
  output_values[1] = input_value & 0xffffffff;

Ensuite, pour recombiner deux valeurs de 32 bits à une valeur de 64 bits:

  input_value = ((int64_t) output_values[0]) << 32) | output_values[1];

La représentation du nombre JS est un double standard ieee, donc vous ne pouvez pas représenter un entier de 64 bits. iirc vous obtenez peut-être 48 bits de précision int réelle dans un double, mais tous les bits JS réduisent à 32 bits de précision (c'est ce que la spécification exige.) si vous avez vraiment besoin d'un int 64 bits dans js vous devrez implémenter votre propre Bibliothèque logique int 64 bits.


JSON lui-même ne se soucie pas des limites d'implémentation. votre problème est que JS ne peut pas gérer vos données, pas le protocole. En d'autres termes, votre code client JS doit utiliser l'une ou l'autre de ces options non parfaites.


Il y a en fait une limitation au niveau de précision JavaScript / ECMAScript à 53 bits pour les entiers (ils sont stockés dans la mantisse d'un tampon mémoire de type "double-like" de 8 octets). La transmission de grands nombres au format JSON ne sera donc pas désérialisée comme prévu par le client JavaScript, ce qui les tronquerait à sa résolution de 53 bits.

> parseInt("10765432100123456789")
10765432100123458000

Voir la constante Number.MAX_SAFE_INTEGER et la fonction Number.isSafeInteger() :

La constante MAX_SAFE_INTEGER a la valeur 9007199254740991 . Le raisonnement derrière ce nombre est que JavaScript utilise des nombres en format à virgule flottante à double précision comme spécifié dans IEEE 754 et ne peut représenter en toute sécurité que des nombres entre -(2^53 - 1) et 2^53 - 1 .

Safe dans ce contexte se réfère à la capacité de représenter les entiers exactement et de les comparer correctement. Par exemple, Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 sera évalué à true , ce qui est mathématiquement incorrect. Voir Number.isSafeInteger() pour plus d'informations.

En raison de la résolution des flottants dans JavaScript, l'utilisation de "nombres à virgule flottante 64 bits" comme vous le proposiez souffrirait de la même restriction.

À mon humble avis, la meilleure option est de transmettre ces valeurs comme du texte. Ce serait encore un contenu JSON parfaitement lisible, et il serait facile de travailler avec au niveau JavaScript.

Une représentation "chaîne pure" est ce que OData spécifie, pour ses types Edm.Int64 ou Edm.Decimal .

Ce que fait l'API Twitter dans ce cas, c'est d'ajouter un champ spécifique ".._str": dans le JSON, en tant que tel:

{
   "id": 10765432100123456789,           // for JSON compliant clients
   "id_str": "10765432100123456789",     // for JavaScript
    ...
}

J'aime beaucoup cette option, car elle serait toujours compatible avec les clients compatibles int64. En pratique, un tel contenu dupliqué dans le JSON ne fera pas trop mal, s'il est déflaté / gzippé au niveau HTTP.

Une fois transmis en tant que chaîne, vous pouvez utiliser des bibliothèques comme strint - une bibliothèque JavaScript pour les entiers codés en chaîne pour gérer de telles valeurs.







64bit