flatbuffers icon indicating copy to clipboard operation
flatbuffers copied to clipboard

[JSON] Floats do not round-trip

Open Muon opened this issue 8 months ago • 4 comments

Insufficient precision is used when printing 64-bit floats to ensure a correct round-trip conversion. (Assuming the conversion from decimal to floating-point is done by rounding to nearest, half to even, as is standard.)

For example,6696.1335444003935 gets printed as 6696.133544400393. However, those round to two different 64-bit floats.

The precision needs to be increased to 17 significant digits for doubles in NumToString.

Muon avatar Apr 08 '25 12:04 Muon

This issue is stale because it has been open 6 months with no activity. Please comment or label not-stale, or this will be closed in 14 days.

github-actions[bot] avatar Oct 07 '25 20:10 github-actions[bot]

This is still the case today.

Muon avatar Oct 09 '25 05:10 Muon

looking over the code, it seems the code makes an attempt to set the precision, just not to the full precision --

template <>
inline std::string NumToString<double>(double t) {
  return FloatToString(t, 12);
}
template <>
inline std::string NumToString<float>(float t) {
  return FloatToString(t, 6);
}

we do also, at one point, call the FloatToString method directly with 17 digits of precision, in idl_parser.cpp

value.constant = FloatToString(field->default_real(), 17);

maybe we can just increase the defaults to 9 and 17?

jtdavis777 avatar Nov 25 '25 00:11 jtdavis777

so, just brute forcing this and making the change causes the tests to fail because 3.14159265359 gets rewritten to 3.14159265359000006 -- technically correct but more digits than necessary.

jtdavis777 avatar Nov 25 '25 01:11 jtdavis777