Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do JSON libraries agree on what's the double-precision value of .5000...1?

Tags:

java

json

c#

If I need to transmit floating-point numbers exactly from C# to JSON to Java, can I use JSON numbers?

If not, why not? What information could be lost and how can I guarantee to retain that?

To be specific, I'm using Json.NET in C# and Jackson (through its class ObjectMapper) in Java.

It looks like double.TryParse is what is ultimately used when Json.NET parses a number to double and Double.parseDouble is what is ultimately used when Jackson ObjectMapper parses a number to double.

Can I expect Microsoft's double.TryParse and Java's Double.parseDouble to agree exactly on the value of every JSON number?

I am concerned because the number of digits in a JSON number is not bounded in ECMA-404, IETF RFC 7159, or json.org. This other question (Maximum number of decimal digits that can affect a double) makes me wonder how much I can trust a common belief that the first block of 17 decimal digits (having discarded leading zeroes), or in fact any bounded number of decimal digits, is sufficient to determine a double-precision floating-point value.

like image 411
Aaron Mansheim Avatar asked Mar 01 '16 19:03

Aaron Mansheim


3 Answers

The JSON part of the question can be safely ignored. In both cases it is just a string that gets parsed. What matters is:

  • Are the data types double identical in both systems.
  • If so does double.TryParse and Double.parseDouble always return the same double value for a set input.
  • And the unasked: Is double really the right data structure here?

As Juunas states, both use the same spec for doubles, so you should be able to consider double identical.

Nothing in either parsing documentation guarantees comparability with the other nor is how the handling of numbers which can not be represented specified in either documentation.

However as you are using doubles here, and (on the assumption you are using doubles with the knowledge they an't right) they are likely "good enough", and if they are not "good enough" then it is likely that doubles the right data structure anyway and you should be looked at a fixed decimal format. How that works with JSON is a different question. :)

like image 131
Michael Lloyd Lee mlk Avatar answered Oct 21 '22 10:10

Michael Lloyd Lee mlk


Well, for floating point numbers the amount of decimals doesn't really matter. What matters is can the number be represented exactly in binary. You might already know some numbers cannot be represented exactly. Floating point is always an approximation.

Since C# and Java use the same spec (IEEE 754), any number Java was able to represent as a double should convert into the exact same binary form.

like image 43
juunas Avatar answered Oct 21 '22 12:10

juunas


No, not every JSON number is strictly convertible with some particular IEEE 754 binary64 (aka double-precision aka "double") number.

In many situations it is good enough to use JSON numbers. It depends on what guarantees you, or the people whose data you are transmitting, will need. Without an agreement outside of JSON there won't be a crisp definition of which JSON numbers are equivalent to which doubles. However, in many situations you can implicitly assume that the needed precision is well within the limits of doubles. Many floating-point numbers are physical measurements made with easily affordable instruments.

Here is one way to make a precise agreement outside of JSON. One writer suggested in an article on the web that if a double is really what you want, then in your JSON you can place an array or object that contains the three components of that structure as integers: sign, exponent, and mantissa. Then people who use the document will need to know the rules of interpreting a double from its three components considered as integers. When the "exponent" integer is 2047, the double value is NaN, and so on.

More elaborate and more standard possibilities exist. You can use HDF5 or comparable if that's what you need. There is already more than one specification of how to represent HDF5 in JSON. Then your JSON document can be self-describing in the manner of HDF5 by annotating your number as having type H5T_IEEE_F64BE.

like image 1
Aaron Mansheim Avatar answered Oct 21 '22 11:10

Aaron Mansheim