Grisu is also proven to be always correct. As mentioned in another comment: you have to define "correct". Grisu is always accurate, but may bail out if you need the shortest or closest result.
Basically: Grisu will always print a number that reads back to the input. However, it may not be able to print the shortest or closest number (when two decimal outputs have the same shortest length). In that case, it knows this, though, and can tell the user.
I would say that the combination of Grisu and Errol is currently the state of the art.
Errol is not the fastest, nor is it (afaik) proven to always return the closest result.
However, combining Grisu with Errol (as fallback) would probably yield the fastest complete algorithm.
> Our original evaluation of Errol against the prior work of Grisu3 was erroneous. The evaluation indicates a 2x speed improvement over Grisu3. However, corrected performance measurements show a 2x speed loss to Grisu3.
Grisu is accurate, but not always optimal. However, it figures out when that happens and lets you bail out to a slower algorithm when that happens. If you want full speed you should use Grisu, and then use Errol as a bailout.
A bit more context: there are 3 important properties when printing floating-point numbers.
- accurateness: you want the printed number to read back to the same number.
- shortness: often you want the shortest decimal representation: "0.3" and not "0.2999999999999999889". The latter is more precise, but reads back to the same number as "0.3".
- closeness: given two decimal representations of the same length, you prefer the one that is closer to the actual number.
I call the combination of these three properties "optimal".
Note that shortness and closeness are not always crucial. For example, a json-encoder could easily drop those, if the encoding is faster without them. Also, some languages drop shortness in favor of printing something closer to the input.
Grisu always produces accurate results. However, it sometimes can't tell if it already has the shortest and closest number. However (by being conservative) it can tell the user when that happens. In that case, one can fall back to another complete algorithm.
The double-conversion library (http://github.com/google/double-conversion) does exactly that. It uses the slower bignum algorithm in these cases.
as does Rhino (Java) https://github.com/mozilla/rhino/blob/master/src/org/mozilla...