News for hackers. Stuff that matters.
Re:Zmij: Faster floating point double-to-string conversion by floitsch on Wednesday December 17, 2025 @03:45PM (#46305277)
Pretty impressive.

When I published Grisu (Google double-conversion), it was multiple times faster than the existing algorithms. I knew that there was still room for improvement, but I was at most expecting a factor 2 or so. Six times faster is really impressive.

Re:Zmij: Faster floating point double-to-string conversion by vitaut on Wednesday December 17, 2025 @04:39PM (#46305885)
Thank you! It means a lot coming from you, Grisu was the first algorithm that I implemented =). (I am the author of the blog post.)
Re:Zmij: Faster floating point double-to-string conversion by andrepd on Wednesday December 17, 2025 @04:57PM (#46306136)
Very interesting!

I wonder how Teju Jaguá compares. I don't see it in the C++ benchmark repo you linked and whose graph you included.

I have contributed an implementation in Rust :) https://crates.io/crates/teju it includes benchmarks which compare it vs Ryu and vs Rust's stdlib, and the readme shows a graph with some test cases. It's quite easy to run if you're interested!

Re:Zmij: Faster floating point double-to-string conversion by vitaut on Wednesday December 17, 2025 @05:05PM (#46306216)
I am not sure how it compares but I did use one idea from Cassio's talk on Teju:

> A more interesting improvement comes from a talk by Cassio Neri Fast Conversion From Floating Point Numbers. In Schubfach, we look at four candidate numbers. The first two, of which at most one is in the rounding interval, correspond to a larger decimal exponent. The other two, of which at least one is in the rounding interval, correspond to the smaller exponent. Cassio’s insight is that we can directly construct a single candidate from the upper bound in the first case.

Re:Zmij: Faster floating point double-to-string conversion by andrepd on Wednesday December 17, 2025 @06:03PM (#46306809)
Indeed! I saw that you linked to Neri's work, so you were aware of Teju Jaguá. I might make a pull request to add it to the benchmark repo when I have some time :)

Another nice thing about your post is mentioning the "shell" of the algorithm, that is, actually translating the decimal significand and exponent into a string (as opposed to the "core", turning f * 2^e into f' * 10^e'). A decent chunk of the overall time is spent there, so it's worth optimising it as well.

Re:Zmij: Faster floating point double-to-string conversion by vlovich123 on Wednesday December 17, 2025 @11:56PM (#46309012)
Any ideas why Rust’s stdlib hasn’t adopted faster implementations?
Re:Zmij: Faster floating point double-to-string conversion by pitaj on Thursday December 18, 2025 @12:30AM (#46309187)
I think code size is one notable reason
Re:Zmij: Faster floating point double-to-string conversion by vitaut on Thursday December 18, 2025 @09:40AM (#46313182)
I am pretty sure Dragonbox is smaller than Ryu in terms of code size because it can compress the tables.
Re:Zmij: Faster floating point double-to-string conversion by Cold_Miserable on Wednesday December 17, 2025 @05:28PM (#46306461)
Already done ages ago. Nothing more of interest.

The bottleneck are the 3 conditionals: - positive or negative - positive or negative exponent, x > 10.0 - correction for 1.xxxxx * 2^Y => fract(log10(2^Y)) 1.xxxxxxxx > 10.0

Re:Zmij: Faster floating point double-to-string conversion by mulle_nat on Wednesday December 17, 2025 @06:13PM (#46306922)
Thank you for the code. I could port this easily to C and it solved a lot of portability issues for me.
Re:Zmij: Faster floating point double-to-string conversion by vitaut on Wednesday December 17, 2025 @11:27PM (#46308891)
I've added a C implementation in https://github.com/vitaut/zmij/blob/main/zmij.c in case you are interested.
Re:Zmij: Faster floating point double-to-string conversion by mulle_nat on Thursday December 18, 2025 @05:33AM (#46311031)
Nice, but it's too late I needed a different API for future use in my custom sprintf so I made mulle-dtostr (https://github.com/mulle-core/mulle-dtostr). On my machine (AMD) that benchmarked in a quick try quite a bit faster even, but I was just checking that it didn't regress too badly and didn't look at it closer.
Re:Zmij: Faster floating point double-to-string conversion by vitaut on Saturday December 20, 2025 @12:00AM (#46333732)
Please note that there is some error in your port:

Error: roundtrip fail 4.9406564584124654e-324 -> '5.e-309' -> 4.9999999999999995e-309

Error: roundtrip fail 6.6302941479442929e-310 -> '6.6302941479443e-309' -> 6.6302941479442979e-309

Error: roundtrip fail -1.9153028533493997e-310 -> '-1.9153028533494e-309' -> -1.9153028533493997e-309

Error: roundtrip fail -2.5783653320086361e-312 -> '-2.57836533201e-309' -> -2.5783653320099997e-309

Re:Zmij: Faster floating point double-to-string conversion by NovemberWhiskey on Wednesday December 17, 2025 @07:13PM (#46307427)
When I saw the title here, my first thought was “wow, these RISC-V ISA extensions are getting out of hand”
Re:Zmij: Faster floating point double-to-string conversion by HexDecOctBin on Wednesday December 17, 2025 @07:49PM (#46307663)
It seems that most research effort goes into better dtoa, and not enough in a better atod. There are probably a dozen dtoa algorithms now, and (I think?) two for atod. Anyone know why?
Re:Zmij: Faster floating point double-to-string conversion by vitaut on Wednesday December 17, 2025 @09:50PM (#46308422)
Good question. I am not familiar with string-to-double algorithms but maybe it's an easier problem? double-to-string is relatively complex, people even doing PhD in this area. There is also some inherent asymmetry: formatting is more common than parsing.
Re:Zmij: Faster floating point double-to-string conversion by mdf on Thursday December 18, 2025 @01:22AM (#46309477)
> formatting is more common than parsing.

Is it, though? It's genuinely hard for me to tell.

There's both serialization and deserialization of data sets with, e.g., JSON including floating point numbers, implying formatting and parsing, respectively.

Source code (including unit tests etc.) with hard-coded floating point values is compiled, linted, automatically formatted again and again, implying lots of parsing.

Code I usually work with ingests a lot of floating point numbers, but whatever is calculated is seldom displayed as formatted strings and more often gets plotted on graphs.

Re:Zmij: Faster floating point double-to-string conversion by adrian_b on Thursday December 18, 2025 @07:37AM (#46311916)
For serialization and deserialization, when the goal is to produce strings that will be read again by a computer, I consider the use of decimal numbers as a serious mistake.

The conversion to string should produce a hexadecimal floating-point number (e.g. with the "a" or "A" printf conversion specifier of recent C library implementations), not a decimal number, so that both serialization and deserialization are trivial and they cannot introduce any errors.

Even if a human inspects the strings produced in this way, comparing numbers to see which is greater or less and examining the order of magnitude can be done as easy as with decimal numbers. Nobody will want to do exact arithmetic computations mentally with such numbers.

Re:Zmij: Faster floating point double-to-string conversion by vitaut on Thursday December 18, 2025 @09:30AM (#46313091)
Think about things like logging and all the uses of printf which are not parsed back. But I agree that parsing is extremely common, just not the same level.
Re:Zmij: Faster floating point double-to-string conversion by dtolnay on Thursday December 18, 2025 @02:34AM (#46309888)
In implementing Rust's serde_json library, I have dealt with both string-to-double and double-to-string. Of the two, I found string-to-double was more complex.

Unlike formatting, correct parsing involves high precision arithmetic.

Example: the IEEE 754 double closest to the exact value "0.1" is 7205759403792794*2^-56, which has an exact value of A (see below). The next higher IEEE 754 double has an exact value of C (see below). Exactly halfway between these values is B=(A+C)/2.

  A=0.1000000000000000055511151231257827021181583404541015625
  B=0.100000000000000012490009027033011079765856266021728515625
  C=0.10000000000000001942890293094023945741355419158935546875
So for correctness the algorithm needs the ability to distinguish the following extremely close values, because the first is closer to A (must parse to A) whereas the second is closer to C:

  0.1000000000000000124900090270330110797658562660217285156249
  0.1000000000000000124900090270330110797658562660217285156251
The problem of "string-to-double for the special case of strings produced by a good double-to-string algorithm" might be relatively easy compared to double-to-string, but correct string-to-double for arbitrarily big inputs is harder.
Re:Zmij: Faster floating point double-to-string conversion by nly on Thursday December 18, 2025 @03:27AM (#46310194)
I guess one aspect of it is that in really high performance fields where you're taking in lots of stringy real inputs (FIX messages coming from trading venues for example, containing prices and quantities) you would simply parse directly to a fixed point decimal format, and only accept fixed (not scientific) notation inputs. Except for trailing or leading zeros there is no normalisation to be done.

Parsing a decimal ASCII string to a decimal value already optimizes well, because you can scale each digit by it's power of 10 in parallel and just add up the result.

Re:Zmij: Faster floating point double-to-string conversion by andrepd on Thursday December 18, 2025 @06:28AM (#46311411)
For those wishing to read up on this subject, an excellent starting point is this comprehensive post by one of the main contributors of the fast algorithm currently used in core:

https://old.reddit.com/r/rust/comments/omelz4/making_rust_fl...

Re:Zmij: Faster floating point double-to-string conversion by vitaut on Thursday December 18, 2025 @09:25AM (#46313050)
> Unlike formatting, correct parsing involves high precision arithmetic.

Formatting also requires high precision arithmetic unless you disallow user-specified precision. That's why {fmt} still has an implementation of Dragon4 as a fallback for such silly cases.

Re:Zmij: Faster floating point double-to-string conversion by amluto on Wednesday December 17, 2025 @11:38PM (#46308938)
I read the post and the companion post:

https://vitaut.net/posts/2025/smallest-dtoa/

And there’s one detail I found confusing. Suppose I go through the steps to find the rounding interval and determine that k=-3, so there is at most one integer multiple of 10^-3 in the interval (and at least one multiple of 10^-4). For the sake of argument, let’s say that -3 worked: m·10^-3 is in the interval.

Then, if m is not a multiple of 10, I believe that m·10^-3 is the right answer. But what if m is a multiple of 10? Then the result will be exactly equal, numerically, to the correct answer, but it will have trailing zeros. So maybe I get 7.460 instead of 7.46 (I made up this number and I have no idea whether any double exists gives this output.) Even though that 6 is definitely necessary (there is no numerically different value with decimal exponent greater than -3 that rounds correctly), I still want my formatter library to give me the shortest decimal representation of the result.

Is this impossible for some reason? Is there logic hiding in the write function to simplify the answer? Am I missing something?

Re:Zmij: Faster floating point double-to-string conversion by vitaut on Thursday December 18, 2025 @12:08AM (#46309067)
This is possible and the trailing zeros are indeed removed (with the exponent adjusted accordingly) in the write function. The post mentions removing trailing zeros without going into details but it's a pretty interesting topic and was recently changed to use lzcnt/bsr instead of a lookup table.
Re:Zmij: Faster floating point double-to-string conversion by nhatcher on Thursday December 18, 2025 @07:21AM (#46311802)
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

Re:Zmij: Faster floating point double-to-string conversion by vitaut on Thursday December 18, 2025 @09:23AM (#46313022)
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.
Re:Zmij: Faster floating point double-to-string conversion by adgjlsfhk1 on Thursday December 18, 2025 @10:12AM (#46313537)
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).
Re:Zmij: Faster floating point double-to-string conversion by vitaut on Thursday December 18, 2025 @11:40AM (#46314997)
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.

Re:Zmij: Faster floating point double-to-string conversion by nhatcher on Thursday December 18, 2025 @10:37AM (#46313975)
Oh wow, I would love to see that if you can share it :)
Re:Zmij: Faster floating point double-to-string conversion by adgjlsfhk1 on Thursday December 18, 2025 @10:42AM (#46314057)
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.
Re:Zmij: Faster floating point double-to-string conversion by vitaut on Friday December 19, 2025 @10:08AM (#46326666)
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.
Re:Zmij: Faster floating point double-to-string conversion by adgjlsfhk1 on Friday December 19, 2025 @11:52PM (#46333706)
Not adding it until complete, but https://github.com/JuliaLang/julia/pull/60439 is the draft.
Re:Zmij: Faster floating point double-to-string conversion by nhatcher on Friday December 19, 2025 @06:37AM (#46324684)
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?

Re:Zmij: Faster floating point double-to-string conversion by vitaut on Friday December 19, 2025 @09:34AM (#46326286)
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.
Re:Zmij: Faster floating point double-to-string conversion by nhatcher on Friday December 19, 2025 @10:54AM (#46327184)
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`
Re:Zmij: Faster floating point double-to-string conversion by vitaut on Friday December 19, 2025 @07:16PM (#46332528)
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!
Re:Zmij: Faster floating point double-to-string conversion by vitaut on Friday December 19, 2025 @07:23PM (#46332572)
Should be fixed now.
Re:Zmij: Faster floating point double-to-string conversion by dtolnay on Friday December 19, 2025 @12:54PM (#46328766)
"1.e-01" is for 0.1, not 1.0.
Re:Zmij: Faster floating point double-to-string conversion by nhatcher on Friday December 19, 2025 @01:41PM (#46329316)
I assume they meant 1.e+00

That is what Schubfach does

Re:Zmij: Faster floating point double-to-string conversion by vitaut on Friday December 19, 2025 @07:25PM (#46332583)
Yeah, that's what I meant.
Re:Zmij: Faster floating point double-to-string conversion by Scaevolus on Thursday December 18, 2025 @11:22AM (#46314718)
Is the large significands table (~19KB) an issue for cache contention in practical use, or are only a small range of significands generally accessed?
Re:Zmij: Faster floating point double-to-string conversion by vitaut on Thursday December 18, 2025 @11:37AM (#46314951)
It depends on the input distribution, specifically exponents. It is also possible to compress the table at the cost of additional computation using the method from Dragonbox.