ulfjack / ryu

Converts floating point numbers to decimal strings
Apache License 2.0
1.2k stars 100 forks source link

Allow customizable switch boundaries for scientific notation. #196

Open maisonobe opened 3 years ago

maisonobe commented 3 years ago

This pull request allows users to customize the limit between decimal and scientific notation. The current version of Ryū is compliant with the Java spec and switches to scientific notation for numbers smaller than 10⁻³ or larger than 10⁺⁷. This is cumbersome in some cases where scientific notation is forbidden. One example is formatting the seconds in a date obeying ISO-8601 standard (or equivalently CCSDS 301.0-B-4 time code formats). In these cases, time in the first millisecond of each minute would be produced in scientific notation. This would imply using a printf-like format (but Ryū-printf is not available in the Java language) or rely on the standard formats with a predefined accuracy, instead of the full-preserving property of Ryū.

The proposed changed simply uses user-customizable values for the limit exponents (-3 and +7 by default), while still preserving the existing API for regular uses.

Of course, this only shifts the problem to a smaller exponent, as in the example above even setting lowExp to -12 would mean the problem arise again in the first picosecond of each minutes. This however can be managed at caller level, by truncating too small values according to the domain.

In the date example above, we know that in the GNSS field absolute dates are accurate at about nanosecond level, and we can decide to truncate at picosecond level so no accuracy is lost in write/parse loops. However, inaccuracies at millisecond level are far too large (as signal travels at the speed of light, 1ms corresponds to 300km…).