Jetons un coup d'oeil au JSON rfc4627
génère:
> io:format("~s~n", [rfc4627:encode({obj, [{"age", 45.99}]})]).
{"age":4.59900000000000019895e+01}
Il se trouve que rfc4627
encode les valeurs à virgule flottante en appelant float_to_list/1
, qui utilise la notation « scientifique » avec 20 chiffres de précision. As Per Hedeland noted on the erlang-questions mailing list in November 2007, c'est un choix étrange:
Une question raisonnable pourrait être la raison pour laquelle float_to_list/1 génère 20 chiffres quand un flotteur 64 bits (alias C double), qui est ce qui est utilisé en interne, ne peut contenir 15 Je ne sais pas ce qu'un flotteur de 128 bits aurait, mais vraisemblablement beaucoup plus de 20, donc ce n'est pas non plus. Je suppose que dans les âges sombres, quelqu'un pensait que 20 était un nombre gentil et pair (j'espère que ce n'était pas moi :-). Le formulaire 6.30000 est bien sûr juste le formatage ~ p/~ w.
Cependant, il se trouve c'est en fait pas le problème! En fait, 45.990000000000002
est égal à 45.99
, de sorte que vous faire obtenir la valeur correcte à l'avant:
> 45.990000000000002 =:= 45.99.
true
Comme il est indiqué ci-dessus, un flotteur 64 bits peut contenir 15 ou 16 chiffres significatifs, mais 45.990000000000002
contient 17 chiffres (comptez-les!). Il semble que votre frontal essaie d'imprimer le numéro avec plus de précision qu'il n'en contient réellement, ce qui rend le numéro différent même s'il s'agit en fait du même numéro.
Les réponses à la question Is floating point math broken? vont beaucoup plus de détails sur les raisons de ce fait réellement sens, étant donné la façon dont les ordinateurs gèrent des valeurs à virgule flottante.
Pourriez-vous publier le code sur le client qui reçoit ces données? Je l'aventure c'est quelque chose à voir avec JavaScript. –