{"slug": "rust-1-98-algebraic-floats-fix-the-8x-c-speed-gap", "title": "Rust 1.98 Algebraic Floats Fix the 8x C++ Speed Gap", "summary": "Rust 1.98, released on August 20, introduces algebraic floating-point methods that address a performance gap where Rust dot products ran 8x slower than C++ on x86_64 CPUs, allowing per-operation reordering for vectorization without undefined behavior. The release also adds format_into and NumBuffer for zero-heap integer formatting, plus String::from_utf16le/from_utf16be and other stabilizations.", "body_md": "Rust 1.98 landed on August 20 with a headline feature the previews missed: algebraic floating-point methods that directly address the long-standing gap where Rust dot products ran **8x slower than C++** on x86_64 CPUs. If you write numerical, audio, graphics, or ML inference code in Rust, this is the release you have been waiting for. Run `rustup update stable`\n\nand read on.\n\n## The Float Problem: Why Rust Was Losing to C++\n\nIn 2025, a [GitHub issue](https://github.com/rust-lang/libs-team/issues/532) demonstrated that a simple Rust dot-product loop ran 8x slower than the equivalent C++ on modern x86_64 hardware. The culprit was not Rust’s optimizer — it was correctness. Rust strictly follows IEEE 754, which mandates that floating-point additions execute left to right. That means `a + b + c + d`\n\nmust be evaluated as `((a + b) + c) + d`\n\n, one operation at a time.\n\nC++ with `-O3`\n\nrelaxes that constraint and lets the compiler reorder operations into `(a + b) + (c + d)`\n\n, which maps directly to SIMD parallel execution. That is where the 8x gap came from. The previous Rust workaround — `fadd_fast`\n\nintrinsics — assumed all inputs were finite, causing undefined behavior if a NaN or infinity appeared. Not exactly production-safe.\n\n## Algebraic Methods: Opt-In Performance, No Undefined Behavior\n\nRust 1.98 adds five new methods to both `f32`\n\nand `f64`\n\n: `algebraic_add`\n\n, `algebraic_sub`\n\n, `algebraic_mul`\n\n, `algebraic_div`\n\n, and `algebraic_rem`\n\n. They signal to the compiler that it may reorder these specific operations for better vectorization. Results may differ slightly from strict IEEE sequential execution — but they are never undefined behavior. The compiler picks valid floating-point values, not garbage.\n\nHere is what a vectorization-friendly dot product looks like in Rust 1.98:\n\n``` php\nfn dot(a: &[f32], b: &[f32]) -> f32 {\n    a.iter().zip(b).fold(0.0_f32, |acc, (x, y)| {\n        acc.algebraic_add(x.algebraic_mul(*y))\n    })\n}\n```\n\nThat is the entire change. The compiler now has permission to generate vectorized code for this loop. Performance gains depend on your workload — simple accumulations can approach the C++ baseline, and numerical kernels previously bottlenecked on sequential float ops should see meaningful improvements.\n\nThis is a more surgical design than C++’s `-ffast-math`\n\n, which applies to every float operation in the compilation unit — you cannot opt specific hot loops in while leaving the rest IEEE-compliant. Rust’s algebraic methods are per-operation, giving you precise control. [Python Speed’s breakdown](https://pythonspeed.com/articles/faster-float-math-rust/) walks through the performance implications in detail.\n\n## format_into: Remove itoa from Your Cargo.toml\n\nThe second headline addition is `format_into`\n\non all primitive integer types, paired with the new `NumBuffer`\n\ntype. It is a stack-allocated, zero-heap, zero-dynamic-dispatch way to turn integers into string slices:\n\n``` js\nlet mut buf = NumBuffer::<u64>::INIT;\nlet s: &str = 1234567u64.format_into(&mut buf);\n```\n\nThe [ itoa crate](https://crates.io/crates/itoa) has served this purpose for years and logs around 200 million downloads per month on crates.io.\n\n`format_into`\n\nbenchmarks on par with it. For new code using primitive integers in performance-critical paths, the stdlib now covers this use case without an external dependency. The `itoa`\n\ncrate still makes sense for its byte-slice API or broader type coverage, but most users can reach for stdlib instead.## Other Additions Worth Noting\n\nRust 1.98 also stabilizes `String::from_utf16le`\n\nand `String::from_utf16be`\n\nfor explicit-endian UTF-16 conversion — a common pain point when processing Windows-native data formats. The `strip_circumfix`\n\nmethod removes a matching prefix and suffix in a single call. And `str::substr_range`\n\n/ `[T]::subslice_range`\n\nreturn the index range of a sub-slice within its parent, simplifying several common string manipulation patterns.\n\nThe type system also gains the ability to shorten `&mut`\n\nlifetimes when unsize-coercing in invariant positions — a narrow but previously frustrating limitation that forced some generic code into unsafe workarounds.\n\n## When Not to Use Algebraic Methods\n\nAlgebraic methods are not appropriate for financial calculations, cryptographic code, or anywhere exact IEEE 754 reproducibility matters. If your test suite verifies exact floating-point output or you are implementing a spec that mandates sequential evaluation, leave `algebraic_*`\n\nalone. For simulation, inference, audio processing, and rendering — anywhere approximate-but-faster is the right tradeoff — this is a clear upgrade.\n\n## Upgrading\n\nRust 1.98 is a standard stable release with full backward compatibility. Existing code compiles without changes. The algebraic methods and `format_into`\n\nare available immediately with no feature flags required:\n\n```\nrustup update stable\n```\n\nThe full release announcement is on the [official Rust blog](https://blog.rust-lang.org/2026/08/20/Rust-1.98.0/). The complete API changelog lives at [releases.rs](https://releases.rs/docs/1.98.0/). Coverage on [Phoronix](https://www.phoronix.com/news/Rust-1.98-Released) digs into the vectorization angle further.", "url": "https://wpnews.pro/news/rust-1-98-algebraic-floats-fix-the-8x-c-speed-gap", "canonical_source": "https://byteiota.com/rust-1-98-algebraic-floats-fix-the-8x-c-speed-gap/", "published_at": "2026-08-22 22:10:35+00:00", "updated_at": "2026-08-22 22:14:05.088963+00:00", "lang": "en", "topics": ["machine-learning", "developer-tools"], "entities": ["Rust", "C++", "IEEE 754", "itoa", "NumBuffer", "Python Speed"], "alternates": {"html": "https://wpnews.pro/news/rust-1-98-algebraic-floats-fix-the-8x-c-speed-gap", "markdown": "https://wpnews.pro/news/rust-1-98-algebraic-floats-fix-the-8x-c-speed-gap.md", "text": "https://wpnews.pro/news/rust-1-98-algebraic-floats-fix-the-8x-c-speed-gap.txt", "jsonld": "https://wpnews.pro/news/rust-1-98-algebraic-floats-fix-the-8x-c-speed-gap.jsonld"}}