{"slug": "zmij", "name": "zmij", "category": "dev-libs", "category_name": "Libraries and frameworks", "description": "", "recommenders": 3, "commenters": 6, "warners": 1, "score": 1.608, "rising": 0.35, "first": "2025-12-18", "latest": "2026-08-20", "why": "zmij[1] is claimed to be significantly faster than all of the tested implementations in the paper.", "why_is_quote": true, "has_verdict": false, "sentiment": {"recommend": 3, "neutral": 1, "compare": 2, "warn": 0}, "spark": [0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0], "listed": true, "loved": [], "caveat": "", "short_quote": "zmij[1] is claimed to be significantly faster than all of the tested implementations in the paper.", "kind": "", "icon": false, "domain": null, "github_repo": "github.com/vitaut/zmij", "official_url": "https://github.com/vitaut/zmij", "pricing": "", "aliases": ["zmij", "Zmij"], "verdict": null, "praise": [{"label": "", "summary": "", "quotes": [{"id": 790066000, "item_id": 49379125, "url": "https://news.ycombinator.com/item?id=49379125", "by": "vitaut", "date": "2026-08-20", "version": null, "stance": "recommend", "quote": "The core of newer methods like yy, xjb and zmij is remarkably simple:", "excerpt": "The core of newer methods like yy, xjb and zmij is remarkably simple: https://vitaut.net/posts/2026/yy-dtoa/. Shortest uscale is basically Schubfach or, rather, it's variant called Teju Jagua and has 2-3 wide multiplications compared to 1 for newer methods. The complexity is optional and comes from squeezing the last few nanoseconds =).", "context": "", "use_case": "Float-to-string conversion", "switched_from": "", "story": "Go 1.27 Is Released"}, {"id": 789961856, "item_id": 49372616, "url": "https://news.ycombinator.com/item?id=49372616", "by": "e4m2", "date": "2026-08-20", "version": null, "stance": "recommend", "quote": "Zmij and xjb are in a league of their own.", "excerpt": "The upstream fmtlib dtoa-benchmark integrates uscale (https://fmtlib.github.io/dtoa-benchmark/results/). It uses C code from Russ Cox's original fpfmt repository (https://github.com/rsc/fpfmt/tree/main/bench/uscalec), which is slightly different from the Go code upthread. Zmij and xjb are in a league of their own. Broadly speaking, dtoa first has to find the shortest decimal representation of the floating-point input", "context": "", "use_case": "", "switched_from": "", "story": "Go 1.27 Is Released"}, {"id": 757257536, "item_id": 47328596, "url": "https://news.ycombinator.com/item?id=47328596", "by": "leni536", "date": "2026-03-10", "version": null, "stance": "recommend", "quote": "zmij[1] is claimed to be significantly faster than all of the tested implementations in the paper.", "excerpt": "zmij[1] is claimed to be significantly faster than all of the tested implementations in the paper. It would have been nice if it was included. [1] https://github.com/vitaut/zmij", "context": "", "use_case": "Float-to-decimal conversion", "switched_from": "", "story": "Converting Binary Floating-Point Numbers to Shortest Decimal Strings"}, {"id": 740988832, "item_id": 46311802, "url": "https://news.ycombinator.com/item?id=46311802", "by": "nhatcher", "date": "2025-12-18", "version": null, "stance": "recommend", "quote": "Your C implentation almost feels... simple!", "excerpt": "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", "context": "", "use_case": "double-to-string conversion", "switched_from": "", "story": "Zmij: Faster floating point double-to-string conversion"}]}], "caveats": [{"label": "", "summary": "", "quotes": [{"id": 741234944, "item_id": 46327184, "url": "https://news.ycombinator.com/item?id=46327184", "by": "nhatcher", "date": "2025-12-19", "version": null, "stance": "warn", "quote": "I get `g++ zmij.cc test.c -o test && ./test` => `0.000000000000001e+15`", "excerpt": "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`", "context": "", "use_case": "double-to-string conversion", "switched_from": "", "story": "Zmij: Faster floating point double-to-string conversion"}]}], "who": [], "tags": [], "use_cases": ["double-to-string conversion", "float-to-string conversion", "float-to-decimal conversion", "floating-point string conversion"], "compared": [{"slug": "xjb", "name": "xjb", "co": 2, "switched_from": 0, "switched_to": 0}], "makers": [{"id": 747851904, "item_id": 46740744, "url": "https://news.ycombinator.com/item?id=46740744", "by": "vitaut", "date": "2026-01-23", "version": null, "stance": "neutral", "quote": "It's on my TODO list for zmij.", "excerpt": "It is possible to compress the table using the technique from Dragonbox (https://github.com/fmtlib/fmt/blob/8b8fccdad40decf68687ec0384f8894ad589615c/include/fmt/format-inl.h#L1050-L1059) at the cost of some perf. It's on my TODO list for zmij.", "context": "", "use_case": "", "switched_from": "", "story": "Floating-Point Printing and Parsing Can Be Simple and Fast"}, {"id": 747071648, "item_id": 46691978, "url": "https://news.ycombinator.com/item?id=46691978", "by": "vitaut", "date": "2026-01-20", "version": null, "stance": "recommend", "quote": "https://github.com/vitaut/zmij does 1 instead of 2-3 costly 128x64-bit multiplications", "excerpt": "The shortest double-to-string algorithm is basically Schubfach or, rather, it's variation Tej\u00fa Jagu\u00e1 with digit output from Dragonbox. Schubfach is a beautiful algorithm: I implemented and wrote about it in https://vitaut.net/posts/2025/smallest-dtoa/. However, in terms of performance you can do much better nowadays. For example, https://github.com/vitaut/zmij does 1 instead of 2-3 costly 128x64-bit multiplications i", "context": "", "use_case": "", "switched_from": "", "story": "Floating-Point Printing and Parsing Can Be Simple and Fast"}, {"id": 741226656, "item_id": 46326666, "url": "https://news.ycombinator.com/item?id=46326666", "by": "vitaut", "date": "2025-12-19", "version": null, "stance": "neutral", "quote": "I started a section to list implementations in other languages", "excerpt": "I started a section to list implementations in other languages: https://github.com/vitaut/zmij?tab=readme-ov-file#other-languages. Once yours is complete feel free to submit a PR to add it there.", "context": "", "use_case": "", "switched_from": "", "story": "Zmij: Faster floating point double-to-string conversion"}], "threads": [{"url": "https://news.ycombinator.com/item?id=46685317", "title": "Floating-Point Printing and Parsing Can Be Simple and Fast", "mentions": 4}, {"url": "https://news.ycombinator.com/item?id=46263821", "title": "Zmij: Faster floating point double-to-string conversion", "mentions": 4}, {"url": "https://news.ycombinator.com/item?id=49365405", "title": "Go 1.27 Is Released", "mentions": 3}, {"url": "https://news.ycombinator.com/item?id=47283884", "title": "Converting Binary Floating-Point Numbers to Shortest Decimal Strings", "mentions": 1}], "sentiment_by_month": {"2025-11": {}, "2025-12": {"recommend": 1}, "2026-01": {"compare": 1, "neutral": 1}, "2026-02": {}, "2026-03": {"recommend": 1}, "2026-04": {}, "2026-05": {}, "2026-06": {}, "2026-07": {}, "2026-08": {"compare": 1, "recommend": 1}, "2026-09": {}, "2026-10": {}}, "versions": [], "version_unnamed": 0, "quotes": [{"id": 790066000, "item_id": 49379125, "url": "https://news.ycombinator.com/item?id=49379125", "by": "vitaut", "date": "2026-08-20", "version": null, "stance": "recommend", "quote": "The core of newer methods like yy, xjb and zmij is remarkably simple:", "excerpt": "The core of newer methods like yy, xjb and zmij is remarkably simple: https://vitaut.net/posts/2026/yy-dtoa/. Shortest uscale is basically Schubfach or, rather, it's variant called Teju Jagua and has 2-3 wide multiplications compared to 1 for newer methods. The complexity is optional and comes from squeezing the last few nanoseconds =).", "context": "", "use_case": "Float-to-string conversion", "switched_from": "", "story": "Go 1.27 Is Released"}, {"id": 789961856, "item_id": 49372616, "url": "https://news.ycombinator.com/item?id=49372616", "by": "e4m2", "date": "2026-08-20", "version": null, "stance": "recommend", "quote": "Zmij and xjb are in a league of their own.", "excerpt": "The upstream fmtlib dtoa-benchmark integrates uscale (https://fmtlib.github.io/dtoa-benchmark/results/). It uses C code from Russ Cox's original fpfmt repository (https://github.com/rsc/fpfmt/tree/main/bench/uscalec), which is slightly different from the Go code upthread. Zmij and xjb are in a league of their own. Broadly speaking, dtoa first has to find the shortest decimal representation of the floating-point input", "context": "", "use_case": "", "switched_from": "", "story": "Go 1.27 Is Released"}, {"id": 789914688, "item_id": 49369668, "url": "https://news.ycombinator.com/item?id=49369668", "by": "cornstalks", "date": "2026-08-19", "version": null, "stance": "compare", "quote": "I\u2019d love to see how that compares to zmij", "excerpt": "I\u2019d love to see how that compares to zmij: https://github.com/dtolnay/dtoa-benchmark", "context": "", "use_case": "", "switched_from": "", "story": "Go 1.27 Is Released"}, {"id": 757257536, "item_id": 47328596, "url": "https://news.ycombinator.com/item?id=47328596", "by": "leni536", "date": "2026-03-10", "version": null, "stance": "recommend", "quote": "zmij[1] is claimed to be significantly faster than all of the tested implementations in the paper.", "excerpt": "zmij[1] is claimed to be significantly faster than all of the tested implementations in the paper. It would have been nice if it was included. [1] https://github.com/vitaut/zmij", "context": "", "use_case": "Float-to-decimal conversion", "switched_from": "", "story": "Converting Binary Floating-Point Numbers to Shortest Decimal Strings"}, {"id": 747854560, "item_id": 46740910, "url": "https://news.ycombinator.com/item?id=46740910", "by": "WiSaGaN", "date": "2026-01-23", "version": null, "stance": "neutral", "quote": "Rust's `serde_json` recently switched to use a new library for floating string conversion: https://github.com/dtolnay/zmij.", "excerpt": "Rust's `serde_json` recently switched to use a new library for floating string conversion: https://github.com/dtolnay/zmij.", "context": "", "use_case": "floating-point string conversion", "switched_from": "", "story": "Floating-Point Printing and Parsing Can Be Simple and Fast"}, {"id": 747826417, "item_id": 46739151, "url": "https://news.ycombinator.com/item?id=46739151", "by": "andrepd", "date": "2026-01-23", "version": null, "stance": "compare", "quote": "Comparing to Zmij, I do wonder how much speedup is there", "excerpt": "I implemented Teju Jagu\u00e1 in Rust, based of the original C impl https://github.com/andrepd/teju-jagua-rs. Comparing to Zmij, I do wonder how much speedup is there on the core part of the algorithm (f2^e -> f10^e) vs on the printing part of the problem (f*10^e -> decimal string)! Benchmarks on my crate show a comparable amount of time spent on each of those parts.", "context": "", "use_case": "", "switched_from": "", "story": "Floating-Point Printing and Parsing Can Be Simple and Fast"}, {"id": 741320448, "item_id": 46332528, "url": "https://news.ycombinator.com/item?id=46332528", "by": "vitaut", "date": "2025-12-19", "version": null, "stance": "neutral", "quote": "", "excerpt": "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!", "context": "", "use_case": "Double-to-string conversion", "switched_from": "", "story": "Zmij: Faster floating point double-to-string conversion"}, {"id": 741234944, "item_id": 46327184, "url": "https://news.ycombinator.com/item?id=46327184", "by": "nhatcher", "date": "2025-12-19", "version": null, "stance": "warn", "quote": "I get `g++ zmij.cc test.c -o test && ./test` => `0.000000000000001e+15`", "excerpt": "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`", "context": "", "use_case": "double-to-string conversion", "switched_from": "", "story": "Zmij: Faster floating point double-to-string conversion"}, {"id": 740988832, "item_id": 46311802, "url": "https://news.ycombinator.com/item?id=46311802", "by": "nhatcher", "date": "2025-12-18", "version": null, "stance": "recommend", "quote": "Your C implentation almost feels... simple!", "excerpt": "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", "context": "", "use_case": "double-to-string conversion", "switched_from": "", "story": "Zmij: Faster floating point double-to-string conversion"}]}