<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/announcing-rust-1-98-0-shdkxou3g" -->

---
title: Announcing Rust 1.98.0 | daily.dev
description: Rust 1.98.0 adds algebraic floating-point methods (algebraic_add, algebraic_sub, algebraic_mul, algebraic_div, algebraic_rem) for f32/f64 that allow compiler...
canonical: https://daily.dev/posts/announcing-rust-1-98-0-shdkxou3g
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Announcing Rust 1.98.0 | daily.dev
og:description: Rust 1.98.0 adds algebraic floating-point methods (algebraic_add, algebraic_sub, algebraic_mul, algebraic_div, algebraic_rem) for f32/f64 that allow compiler...
og:url: https://daily.dev/posts/announcing-rust-1-98-0-shdkxou3g
og:image: https://api.daily.dev/og/posts/shDKXoU3g.png
og:image:alt: Announcing Rust 1.98.0
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Announcing Rust 1.98.0

**[Lobsters](https://daily.dev/sources/lobsters)** · 4 min read · 0 upvotes · 0 comments

## Summary

Rust 1.98.0 adds algebraic floating-point methods (algebraic_add, algebraic_sub, algebraic_mul, algebraic_div, algebraic_rem) for f32/f64 that allow compiler optimizations similar to -ffast-math, at the cost of non-determinism but never undefined behavior. Integer types gain a format_into method for buffered formatting that performs comparably to the itoa crate. The release also stabilizes a documentation guarantee fixing a prior ManuallyDrop/Box undefined-behavior interaction (fixed in 1.96.0), plus a list of newly stabilized APIs including str::substr_range, NumBuffer, String::from_utf16le/be variants, and Atomic<T> helper methods.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://blog.rust-lang.org/2026/08/20/Rust-1.98.0>

## Questions this post answers

### What do the new algebraic_add, algebraic_sub, and other algebraic methods on f32 and f64 do in Rust 1.98.0?

Rust 1.98.0 stabilizes algebraic_add, algebraic_sub, algebraic_mul, algebraic_div, and algebraic_rem on f32 and f64, letting the compiler apply real-number algebraic properties like associativity even though floating-point math does not strictly satisfy them. This enables optimizations similar to -ffast-math in other languages, such as reordering a+b+c+d for vectorization, and results are non-deterministic but never undefined behavior.

_Track how algebraic float methods affect numeric code performance as you upgrade Rust toolchains via daily.dev._

### How fast is the new format_into method for integers in Rust 1.98.0 compared to the itoa crate?

The format_into method, stabilized on all primitive integer types in Rust 1.98.0, performs similarly to the itoa crate according to the itoa-benchmark repository, since it bypasses much of the dynamic dispatch involved in buffered write! formatting. It takes a &mut NumBuffer<Self> and returns a borrowed &str, making it a viable standard-library replacement for itoa and similar dependencies.

_Developers weighing standard-library formatting against crates like itoa can follow such tradeoffs on daily.dev._

### Is it undefined behavior to move a ManuallyDrop<Box<T>> after calling ManuallyDrop::drop on it in Rust?

No, moving a ManuallyDrop<Box<T>> after ManuallyDrop::drop has been called is not undefined behavior as of Rust 1.96.0, which fixed a compiler bug that previously made this UB. Rust 1.98.0 updates the ManuallyDrop documentation to make this a stable guarantee going forward, as detailed in RFC 3336.

_Rust developers relying on ManuallyDrop and Box semantics can keep up with such stability guarantees via daily.dev._

## Community take

How the wider developer community reacted, aggregated from 2 discussions and 15 comments across lobsters, hackernews (as of 2026-08-21).

**TL;DR:** Discussion centers almost entirely on the new algebraic float methods, with technical debate about how associativity/commutativity enable optimization and interest in ergonomic ways to use them, alongside a brief note appreciating Rust's slower feature pace.

**Sentiment:** 55% positive · 40% mixed · 5% skeptical

**The case for**

- Detailed explanations show algebraic operations enable not just SIMD but also instruction-level parallelism and latency reduction in scalar code.
- Some see potential for a user-defined Algebraic<T> wrapper or proc-macro approach to make the feature more ergonomic.
- One commenter praises the smaller, more restrained scope of recent Rust releases.

**The pushback**

- A concern was raised that reassociation and fma fusion can break careful rounding-error control relied on by techniques like double-double arithmetic.
- Scoped operator overloading for algebraic methods was discussed as desirable but was previously considered and rejected for a wrapper-type approach.

**By community**

- lobsters (positive): Deep technical thread exploring why and how algebraic float operations enable optimization, plus ideas for making them easier to use ergonomically.
- hackernews (positive): Brief comment welcoming the trend of fewer new features per release.

**Open questions**

- Is there a good ergonomic way (scoped operator overloading, proc macros, or a wrapper type) to use algebraic methods without verbose method calls?
- How much does reassociation/fma fusion from algebraic operations risk breaking precision-sensitive techniques like double-double arithmetic?

**Highlights**

> > I'm trying to think of an example where reordering floating point operations would allow you to use something like SIMD where you couldn't before. This isn't just for vectorization. A fundamental throughput optimization (whether done manually or automatically) is to restructure dataflow graphs to reduce or eliminate latency bottlenecks. As an example, you can replace ((a + b) + c) + d with (a + b) + (c + d) if addition is associative (or you treat it as associative as with Rust's algebraic_add). When applied to loops (where it really matters) and optimizing for instruction-level parallelism, you usually also exploit commutativity, so you'd compute (a + c) + (b + d) rather than (a + b) + (c + d). Commutativity is also important for efficiently vectorizing a summation loop since you otherwise waste time in the inner loop on shuffles or horizontal adds. But the fundamental enabler for parallelism is associativity, not commutativity. [1] Just to drive home the point about how this can be relevant for purely scalar code. An fadd execution unit is usually fully pipelined (each unit can sustain 1 fadd per cycle) while fadd latency is usually 2-4 cycles depending on the chip. Let's take a slightly older but representative micro-architecture like Skylake with 4-cycle fadd (addps) latency and 2 fadd ports. Then a left-chaining fadd loop with n additions (with n large enough to enter a steady state) will take ~4n cycles. That is 8x slower than the scalar throughput limit (8x rather than 4x since there are 2 ports). [1] Incidentally, IEEE 754 addition _is_ commutative outside of corner cases like adding two NaNs where the NaN bit patterns are different, which isn't relevant here.
> — [pervognsen on lobsters · 1 points, 1 comments](https://lobste.rs/s/hbjeir/announcing_rust_1_98_0#c_dnmonr)

> Does anyone know if something like scoped replacement of infix operators has been considered? It would be notationally nice to be able to say that within a certain scope, any occurrence of `+` means `algebraic_add` (or `saturating_add` or whatever other special variant). Especially these new algebraic math functions are likely to occur in quite long and complicated expressions that would end up a lot more readable if the operators could be temporarily overloaded. I'm imagining something like     fn foo(x: f64, y: f64) -> f64 {         let z = {             #![infix_replace(+, algebraic_add)]            x+y // Actually x.algebraic_add(y). Imagine a long and complicated expression here.         };        z+x+y // Normal addition      } More likely, you'd have an `AlgebraicAdd` trait that mirrors `Add`, and an attribute like `#![add_replace(AlgebraicAdd)]` for each of the infix operators. It would also let you turn on things like explicit checked arithmetic (in every compilation mode) for certain specified functions/scopes without getting very verbose. (I know operator overloading is a contentious topic. While I'm personally a huge fan of freely overloadable/extensible infix operators à la Haskell, I do understand why Rust isn't considering that. A limited, scoped variant might still be worth discussing though.)
> — [gspr on lobsters · 1 points, 3 comments](https://lobste.rs/s/hbjeir/announcing_rust_1_98_0#c_s6h5n1)

> Having read that recently, I was interested by yesterday’s article on [double-double](https://lobste.rs/s/mxnn9v/double_double_31_digits_precision) which warns that reassociation and fma fusion break the kind of careful control over rounding errors that double-double relies on.
> — [fanf on lobsters · 1 points](https://lobste.rs/s/hbjeir/announcing_rust_1_98_0#c_hgyein)

> this could have been solved with making an `Algebraic<T>` wrapper for integers, as was done with `Wrapping<T>`. this was [considered and rejected](https://github.com/rust-lang/libs-team/issues/532#issuecomment-2630439118), although it could be done in a user library.
> — [goldstein on lobsters · 4 points](https://lobste.rs/s/hbjeir/announcing_rust_1_98_0#c_rpvz07)

> I really like we are getting less new features on each release overtime. It feels that language is currently in a sweet spot that should be protected from new features creep!
> — [ammarabouzor on hackernews](https://news.ycombinator.com/item?id=49379814)

**Source threads**

- [lobsters](https://lobste.rs/s/hbjeir/announcing_rust_1_98_0) · 33 points · 13 comments
- [hackernews](https://news.ycombinator.com/item?id=49378813) · 17 points · 2 comments

## Similar posts on daily.dev

- [Rust language adds algebraic floating-point methods](https://daily.dev/posts/rust-language-adds-algebraic-floating-point-methods-jimyxkos8) · InfoWorld · 1 upvotes · 0 comments
- [Faster floating point math with Rust’s new API](https://daily.dev/posts/faster-floating-point-math-with-rust-s-new-api-zyoed6fm9) · Lobsters · 0 upvotes · 0 comments
- [Announcing Rust 1.97.0](https://daily.dev/posts/announcing-rust-1-97-0-fqxhq3pfj) · Rust · 22 upvotes · 0 comments

---

Tags: [#rust](https://daily.dev/tags/rust)

[View this post on daily.dev](https://daily.dev/posts/announcing-rust-1-98-0-shdkxou3g)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Announcing Rust 1.98.0","url":"https://daily.dev/posts/announcing-rust-1-98-0-shdkxou3g","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/announcing-rust-1-98-0-shdkxou3g"},"datePublished":"2026-08-21T07:59:49.814Z","dateModified":"2026-08-21T12:45:44.552Z","description":"Rust 1.98.0 adds algebraic floating-point methods (algebraic_add, algebraic_sub, algebraic_mul, algebraic_div, algebraic_rem) for f32/f64 that allow compiler...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/10c030b2429f801a5aed8756bdece9d2?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/10c030b2429f801a5aed8756bdece9d2?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Lobsters","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Lobsters","logo":"https://media.daily.dev/image/upload/s--tl8v_Fku--/f_auto,t_logo/v1698841318/logos/lobste.jpg","url":"https://daily.dev/sources/lobsters"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/announcing-rust-1-98-0-shdkxou3g","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"rust","timeRequired":"PT4M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Lobsters","item":"https://daily.dev/sources/lobsters"},{"@type":"ListItem","position":3,"name":"Announcing Rust 1.98.0"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/announcing-rust-1-98-0-shdkxou3g#faq","mainEntity":[{"@type":"Question","name":"What do the new algebraic_add, algebraic_sub, and other algebraic methods on f32 and f64 do in Rust 1.98.0?","acceptedAnswer":{"@type":"Answer","text":"Rust 1.98.0 stabilizes algebraic_add, algebraic_sub, algebraic_mul, algebraic_div, and algebraic_rem on f32 and f64, letting the compiler apply real-number algebraic properties like associativity even though floating-point math does not strictly satisfy them. This enables optimizations similar to -ffast-math in other languages, such as reordering a+b+c+d for vectorization, and results are non-deterministic but never undefined behavior. Track how algebraic float methods affect numeric code performance as you upgrade Rust toolchains via daily.dev."}},{"@type":"Question","name":"How fast is the new format_into method for integers in Rust 1.98.0 compared to the itoa crate?","acceptedAnswer":{"@type":"Answer","text":"The format_into method, stabilized on all primitive integer types in Rust 1.98.0, performs similarly to the itoa crate according to the itoa-benchmark repository, since it bypasses much of the dynamic dispatch involved in buffered write! formatting. It takes a &mut NumBuffer<Self> and returns a borrowed &str, making it a viable standard-library replacement for itoa and similar dependencies. Developers weighing standard-library formatting against crates like itoa can follow such tradeoffs on daily.dev."}},{"@type":"Question","name":"Is it undefined behavior to move a ManuallyDrop<Box<T>> after calling ManuallyDrop::drop on it in Rust?","acceptedAnswer":{"@type":"Answer","text":"No, moving a ManuallyDrop<Box<T>> after ManuallyDrop::drop has been called is not undefined behavior as of Rust 1.96.0, which fixed a compiler bug that previously made this UB. Rust 1.98.0 updates the ManuallyDrop documentation to make this a stable guarantee going forward, as detailed in RFC 3336. Rust developers relying on ManuallyDrop and Box semantics can keep up with such stability guarantees via daily.dev."}}]}
```

