Ryū: Fast Float-To-String Conversion
pldi18.sigplan.org
pldi18.sigplan.org
This is because 1/2 is representable as a fraction with 10 in the denominator: 5/10. All fractional digits after the binary point are just powers of 1/2, thus powers of 5/10. Division by ten in decimal doesn't produce any repeating digits.
Here is where the above is slightly misleading, though. The number of decimal digits to capture that exact decimal value of a binary floating point with an n-bit mantissa may be far in excess of the actual decimal precision that is contained in an n-bit mantissa.
In the case of the IEEE 64 bit double we need 17 decimal digits to capture a printed decimal representation which will reproduce the original double. That representation isn't the exact decimal number; much more than 17 digits may be required to get the exact decimal value. The exact decimal value is, I think, rarely of interest. In an ordinary application of floating point numbers, we don't print double values to, say, 30 digits of precision; anything after 17 is "junk".
In the other direction, only 15 decimal digits of precision are guaranteed to be preserved by the representation, so in a 17 digit print, digits 16 and 17 are also "dodgy"; they serve only to record the object exactly.
The author even goes through an explicit example.
https://dl.acm.org/citation.cfm?id=3192369
That's really appreciated; thanks.
Is Ryu.jl significantly faster than what's in Base? Is there already an open issue somewhere?
I don't see an issue about it at the moment. I guess we just expect Jacob to PR it at some point. IIRC he also wrote the Grisu implementation that's in Base.
I'm very interested in how detailed and coordinated the Julia team has become regarding the longer term future of Julia. Admirable effort all around.
If you are starting from scratch, and want to support only platforms that support IEEE754 in hardware, and so on, then yes, just serialize the raw bits.
(not quite the same thing but heading in that direction)
That's not "faking it", that using fixed point numbers [1]. They are a great alternative if the numbers stay in roughly the same magnitude, and are much saner when dealing with e.g. money.
Also have a look at Grisu3, Dragon4, dtoa, and the printf implementations of glibc and musl.
Ryu is somewhat faster for doubles, though SwiftDtoa has support for 80-bit and float out of the box, which is nice, and we have some further perf improvements planned. Both are considerably faster than any of the alternatives (some perf data in the original Swift PR: https://github.com/apple/swift/pull/15474), and both pass our fairly intensive test suite.
musl's implementation is also interesting for reasons of simplicity.