A double-to-string conversion algorithm based on Schubfach and yy with implementations in C and C++
- Round trip guarantee
- Shortest decimal representation
- Correct rounding
- High performance
- Fast compile time
- IEEE 754
doubleandfloatsupport - Safer API than classic
dtoa - Negative zero dependencies
- Small, clean codebase consisting of one source file and an optional header
- Permissive license
#include "zmij.h"
#include <stdio.h>
int main() {
char buf[zmij::double_buffer_size];
zmij::write(buf, sizeof(buf), 5.0507837461e-27);
puts(buf);
}Żmij v1 is more than 4x faster than Ryū used by multiple C++ standard library implementations, 9x faster than double-conversion and ~2.5x faster than Schubfach on dtoa-benchmark run on Apple M1.
| Function | Time (ns) | Speedup |
|---|---|---|
| ostringstream | 871.431 | 1.00x |
| sprintf | 735.292 | 1.19x |
| double-conversion | 83.332 | 10.46x |
| to_chars | 42.808 | 20.36x |
| ryu | 36.809 | 23.67x |
| schubfach | 24.721 | 35.25x |
| fmt | 22.224 | 39.21x |
| dragonbox | 20.532 | 42.44x |
| yy | 14.006 | 62.22x |
| xjb64 | 10.542 | 82.66x |
| zmij | 8.661 | 100.62x |
| null | 0.946 | 921.13x |
Conversion time (smaller is better):
ostringstream and sprintf are excluded due to their significantly slower
performance.
On EPYC Milan (AMD64) running Linux, Żmij is approximately 2.8× faster than Ryū and 5× faster than double-conversion when compiled with GCC 11.5.
| Function | Time (ns) | Speedup |
|---|---|---|
| ostringstream | 958.889 | 1.00x |
| sprintf | 563.022 | 1.70x |
| double-conversion | 95.706 | 10.02x |
| to_chars | 67.115 | 14.29x |
| ryu | 54.144 | 17.71x |
| schubfach | 44.435 | 21.58x |
| fmt | 40.098 | 23.91x |
| dragonbox | 30.896 | 31.04x |
| yy | 26.959 | 35.57x |
| xjb64 | 19.275 | 49.75x |
| zmij | 19.194 | 49.96x |
| null | 2.766 | 346.72x |
Compile time is ~135ms by default and ~180ms with optimizations enabled as measured by
% time c++ -c zmij.cc [-O2]
taking the best of 3 runs.
- C++: https://github.com/vitaut/zmij/blob/main/zmij.cc (reference implementation)
- C: https://github.com/vitaut/zmij/blob/main/zmij.c
- Rust: https://github.com/dtolnay/zmij
- Zig: https://github.com/de-sh/zmij
- 1 instead of 3 multiplications by a power of 10 in the common case
- Faster logarithm approximations
- Faster division and modulo
- Fewer conditional branches
- More efficient significand and exponent output
- Improved storage of powers of 10
- SIMD support
Żmij (pronounced roughly zhmeey or more precisely /ʐmij/) is a Polish word that refers to a mythical dragon- or serpent-like creature, continuing the dragon theme started by Steele and White.
A nice bonus is that the name even contains a "floating point" in its first letter. And to quote Aras Pranckevičius, "Żmij is also literally a beast."
We would like to express our gratitude to the individuals who have made Żmij possible:
-
Victor Zverovich (@vitaut) - Original author and maintainer of Żmij.
-
Tobias Schlüter (@TobiSchluter) - Contributed significant performance and portability improvements, including SIMD/SSE support and core algorithm refinements that enhance execution speed and cross-platform compatibility.
-
Dougall Johnson (@dougallj) – Authored the NEON implementation and contributed many optimization ideas, substantially improving performance on ARM platforms.
-
Alex Guteniev (@AlexGuteniev) - Contributed multiple fixes and improvements across build systems, platform compatibility, and testing infrastructure.
-
Xiang JunBo (@xjb714) - Contributed high-performance BCD digit extraction algorithm and additional optimization ideas used across scalar and SIMD code paths.
-
David Tolnay (@dtolnay) - Created and maintains the Rust port of Żmij, expanding the algorithm's reach and adoption in the Rust ecosystem.
-
Raffaello Giulietti - Author of the Schubfach algorithm, whose work forms a foundational basis for Żmij.
-
Yaoyuan Guo (@ibireme) - Author of the yy algorithm, whose ideas influenced key optimizations used in Żmij.
-
Cassio Neri (@cassioneri) - Proposed the single-candidate rounding strategy used in Żmij.
-
Junekey Jeon (@jk-jeon) - Author of the Dragonbox algorithm, which informed design and benchmarking comparisons for Żmij, as well as the
to_decimalAPI. -
Community contributors who provided feedback, issues, suggestions, and occasional commits, helping improve the robustness and performance of Żmij.



