
Converting floats to strings - jsnell
http://www.corsix.org/content/converting-floats-to-strings-part-1
======
lifthrasiir
> Often the problem is framed as "converting a floating point number to the
> shortest possible decimal string representation", but this framing is
> neither neccessary nor sufficient for implementing the %e / %f / %g formats
> of sprintf.

This sentence is crucial for anyone wants to implement the float-to-decimal
conversion. There exists a Grisu-inspired analogue for this problem but to my
current knowledge it is not well described in any known literature. I had to
fully analyze the analogue and recreate my (slightly improved) version of the
algorithm for Rust [1]. It is not too complex once you understood but annoying
enough to derive again.

[1] [https://github.com/rust-
lang/rust/blob/f8d485f/src/libcore/n...](https://github.com/rust-
lang/rust/blob/f8d485f/src/libcore/num/flt2dec/strategy/grisu.rs#L439-L683)

------
corsix
The end of the post alludes to part 2 ("how to adapt nd_print into something
which can behave like the %e, %f, and %g formats of sprintf"), which alas I've
yet to get around to writing. There'll also be at least one more part after
that detailing the bag of performance tricks which can be used to turn the
described algorithm into something very competitive. Alternatively, you can
jump to the conclusion by just reading the implementation I wrote for LuaJIT
[1], though obviously that won't give you the narrative of _why_ things are
the way they are.

[1]
[https://github.com/LuaJIT/LuaJIT/blob/cf2dfaf3b4eef9b2de32d3...](https://github.com/LuaJIT/LuaJIT/blob/cf2dfaf3b4eef9b2de32d3be962b0336c3fe7dd1/src/lj_strfmt_num.c)

------
to3m
Similar approach, I think, by Russ Cox:
[https://research.swtch.com/ftoa](https://research.swtch.com/ftoa)

Starts with an int->string conversion, then does the rest with string
manipulation - strings, of course, being bignums with a somewhat wasteful BCD
representation.

~~~
userbinator
_Why are some converters more complicated than this? Because you can make them
a little faster. On my laptop, glibc 's sprintf(buf, "%.50e", M_PI) is about
15 times faster than an equivalent print using the code above, because the
implementation of sprintf uses much more sophisticated mathematics to speed
the conversion._

He missed an opportunity to name the article "Floating Point to Decimal
Conversion is Easy and Not Fast" (in reference to
[https://swtch.com/~rsc/regexp/regexp1.html](https://swtch.com/~rsc/regexp/regexp1.html))

(When did he start writing articles in Go? IMHO the syntax is close enough to
C to make skimming through easy enough, but confusing to look at in detail for
the majority who will have likely far more experience with C than Go.)

------
orionblastar
In 1986 I did that in Turbo Pascal 3.0 for DOS. Had a bug with the round
function so I made my own nround that converted the floating point to a string
then parsed the string to find the right rounding and converted it back to a
float. I was the only person in class to get the correct answer and graded
down by my professor and accused of hacking.

------
panic
musl libc also uses base-1000000000 bignums for float formatting:
[https://git.musl-
libc.org/cgit/musl/tree/src/stdio/vfprintf....](https://git.musl-
libc.org/cgit/musl/tree/src/stdio/vfprintf.c#n179)

------
nerdponx
I love learning about all the complexity behind things we do every day and
never stop to think about.

------
userbinator
Interesting. This alternative algorithm is very reminiscent of conversion to
[https://en.wikipedia.org/wiki/Binary-
coded_decimal](https://en.wikipedia.org/wiki/Binary-coded_decimal) .

------
gumby
I just have to whine that I have always hated the construct "convert to
string".

You don't convert a car to a photograph when you take a picture, and neither
do you do any "conversion" when you construct a string that represents the
same value as is represented by the bit pattern of your double or float.

This sounds like some weird linguistic pedantry, and perhaps it is, but I
suspect this usage causes confusion for a number of beginning programmers.

~~~
neilparikh
Maybe a better phrase would be "project to a string", similar to how taking a
picture is projecting something from 3D to 2D?

~~~
c22
How about "transmogrify"?

~~~
inimino
OP's complaint seems to be that "convert" suggests changing in place, which
"transmogrify" suggests even more strongly.

------
khanan
Now, in Python3... :D

~~~
andars
[https://github.com/python/cpython/blob/5d75f441ef0a3cfe7af0d...](https://github.com/python/cpython/blob/5d75f441ef0a3cfe7af0d865db2530528e424818/Python/dtoa.c#L2272)

