r/cpp {fmt} 14d ago

A complete floating-point to_chars in 18 kB

https://vitaut.net/posts/2026/complete-to-chars/
71 Upvotes

13 comments sorted by

21

u/jwakely libstdc++ tamer, LWG chair 14d ago

Wonderful work. Have you compared it to Cassio Neri's Teju Jagua? That's what we're planning to use in GCC instead of Ryu.

13

u/aearphen {fmt} 14d ago

Thank you! Teju Jagua is a nice algorithmic improvement of Schubfach but unfortunately I don't have any numbers. I would expect it to be an improvement over Ryu both in terms of perf and simplicity but you could do even better with yy's approach (1 wide multiplication instead of 2-3): https://vitaut.net/posts/2026/yy-dtoa/.

4

u/jk-jeon 12d ago

Oh, you wrote a post explaining this algorithm. I'll probably have a deep look when I get some time. Thanks for writing it!

By the way, how dare you deliberately discard the lineage of boxed (schubfach-ed) dragons! Well, if you did so, Zmij would have looked like a variant of dragonbox when it's not so I guess it's maybe my fault of preoccupying that name combination😂

2

u/aearphen {fmt} 12d ago

I vibe coded a little visualization to help myself better understand how it works =)

3

u/aearphen {fmt} 13d ago

Actually I did find a comparison of Zmij and Teju although in Rust: https://github.com/dtolnay/dtoa-benchmark#results. Zmij was more than 2x faster at the time of comparison which is not very surprising knowing the algorithms.

1

u/WeeklyAd9738 13d ago edited 13d ago

Does Zmij support C++23 "Fixed width floating-point types" like std::to_chars: float16_t, float32_t, float64_t, float128_t, bfloat16_t?

3

u/aearphen {fmt} 13d ago

Not yet, but those should be easy to add. The hardest is float128_t but all the functionality is already there because binary128 is already supported via long double on certain platforms.

2

u/WeeklyAd9738 13d ago

Thanks for the reply. I think it would be great if Zmij provided those overloads.

One thing I found lacking in the std::to_chars API is the maximum buffer length required by a particular (floating-point) type. Having it as a constant IMO simplifies the code and enables more efficiency. This also applies when converting integers to chars. Are there any plans for supporting integral types? If so, Zmij would be a great drop-in replacement for std::to_chars going forward.

Thanks.

5

u/aearphen {fmt} 13d ago

Yeah, lack of buffer sizes in to_chars is super annoying and Zmij provides them in the main API: https://github.com/vitaut/zmij/blob/ca75e8b12b6935ab3c6b7e160864a70c40f49bf8/zmij.h#L274-L300. There is some ongoing work on integers as well: https://github.com/vitaut/zmij/issues/40.

5

u/WeeklyAd9738 13d ago

What are the chances of libstdc++'s to_chars algorithm being updated to Zmij? There seems to be quite a difference in performance and compiled size.

11

u/jwakely libstdc++ tamer, LWG chair 13d ago

If somebody provides a suitable patch and shows benchmarks there's a very high chance, otherwise none at all. We already have patches and benchmarks for Teju Jagua and will go with that unless somebody does the work to show Zmij is better.

3

u/aearphen {fmt} 12d ago

FWIW I made the license compatible in case anyone is interested in integrating it.