# Slight loss of precision when parsing JSON

Exporting to JSON is working well for me under 11.3. The issue present in previous versions seem to be solved:

n1 = 1755.8118873183587;
json = ExportString[{"n" -> n1}, "JSON"]
(*
"{
\"n\":1.7558118873183587e3
}"
*)


However, I do see a small loss of precision when I import this back:

n2 = <|ImportString[json, "JSON"]|>["n"];
FullForm[n2]
(* 1755.8118873183589 *)


Notice that the last digit is 9 instead of 7.

RealDigits[n1] === RealDigits[n2]
(* False *)


This small difference doesn't happen with other formats such as CSV:

{{n3}} = ImportString[ExportString[n1, "CSV"], "CSV"];
RealDigits[n1] === RealDigits[n3]
(* True *)


I am using Windows 10 and also reproduced this in the cloud.

Why is this happening? I am not sure that this is a bug as n1==n2 returns True, but still, if there is a way to avoid this behavior I would like to know.

UPDATE: I have confirmed this issue with Wolfram Support [CASE:4231647]. In the meanwhile, I have found that the loss of precision can be avoided like this:

Needs["GeneralUtilities"];
"filename.json" // ReadString // JSONToolsFromJSON // ToAssociations

• Check out 1.7558118873183587*10^3 // FullForm.The float is read in, then multiplied by 10^3. In "CSV" the number is not stored in scientific notation and hence doesn't have this problem. – Chip Hurst Feb 19 at 18:53
• Avoiding machine precision seems to make the exporter avoid scientific notation: json = ExportString[{"n" -> SetPrecision[n1, 17]}, "JSON"] – Chip Hurst Feb 19 at 18:56
• Based on @ChipHurst comment, I think that in the JSON parser, the scientific notation e is being replaced by *10^ instead of *^ – Gustavo Delfino Feb 19 at 19:09