Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This blows my mind TBH. I used to say a few years back that Ryu is my favorite modern algorithm but it felt so complicated. Your C implentation almost feels... simple!

Congratulations, can't wait to have some time to study this further





Thank you! The simplicity is mostly thanks to Schubfach although I did simplify it a bit more. Unfortunately the paper makes it appear somewhat complex because of all the talk about generic bases and Java workarounds.

I've just started a Julia port and I think it will be even cleaner than the C version (mostly because Julia gives you a first class (U)Int128 and count leading zeros (and also better compile time programming that lets you skip on writing the first table out explicitly).

Cool, please share once it is complete.

C++ also provides countl_zero: https://en.cppreference.com/w/cpp/numeric/countl_zero.html. We currently use our own for maximum portability.

I considered computing the table at compile time (you can do it in C++ using constexpr) but decided against it not to add compile-time overhead, however small. The table never changes so I'd rather not make users pay for recomputing it every time.


Oh wow, I would love to see that if you can share it :)

Once I finish it, I'll be PRing to the Julia repo (to replace the current Ryu version), and I'll drop a link here.

I started a section to list implementations in other languages: https://github.com/vitaut/zmij?tab=readme-ov-file#other-lang.... Once yours is complete feel free to submit a PR to add it there.

Not adding it until complete, but https://github.com/JuliaLang/julia/pull/60439 is the draft.

Quick question, if you are still around :).

I have been doing some tests. Is it correct to assume that it converts 1.0 to "0.000000000000001e+15".

Is there a test suite it is passing?


It converts 1.0 to "1.e-01" which reminds me to remove the trailing decimal point =). dtoa-benchmark tests that the algorithm produces valid results on its dataset.

So if I use:

    #include "zmij.h"
    #include <stdio.h>

    int main() {
        char buf[zmij::buffer_size];
        zmij::dtoa(1.0, buf);
        puts(buf);
    }
I get `g++ zmij.cc test.c -o test && ./test` => `0.000000000000001e+15`

My bad, you are right. The small integer optimization should be switched to a different output method (or disabled since it doesn't provide much value). Thanks for catching this!

Should be fixed now.

"1.e-01" is for 0.1, not 1.0.

I assume they meant 1.e+00

That is what Schubfach does


Yeah, that's what I meant.



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: