{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreiamgfkopg2ppcphcn25hecxe2ddt65zfkovoh6s2qqeqmya42a3ku",
    "uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3mnsfgedzpmi2"
  },
  "path": "/t/infinite-precision-intermediate-arithmetic-how-much-would-break/24383#post_8",
  "publishedAt": "2026-06-08T18:18:30.000Z",
  "site": "https://internals.rust-lang.org",
  "tags": [
    "https://en.wikipedia.org/wiki/Interval_arithmetic#Interval_operators",
    "https://rust.godbolt.org/z/c3fT4GcvE"
  ],
  "textContent": "zackw:\n\n> I'm sure there are a whole bunch of problems with this idea\n\nIn green-field there's a version of this that works great, actually. I don't think it'd be feasible to more Rust's default numerics to doing it, but for something new (or maybe a new type in Rust?) it actually works wonderfully.\n\nBasically, you have a const-generic `Int<MIN, MAX>` type that represents values in `MIN <= x <= MAX`. A literal `4` has type `Int<4, 4>`. And you use the well-known rules (https://en.wikipedia.org/wiki/Interval_arithmetic#Interval_operators) to expand the range accordingly.\n\nFor example, in `(a + b) / 2` if `a` and `b` are both `Int<-10, 100>`, then `a + b` has type `Int<-20, 200>` and `2` has type `Int<2, 2>`, and thus `(a + b) / 2` _also_ has type `Int<-10, 100>`. Exactly back to the original type, computing the correct value, and zero need to think about wrapping and such _ever_. Thus no need for `u32::midpoint` and friends, plus it automatically works for things we don't have methods for today: a binomial filter like `(a + 3 * b + 3 * c + d)/8` _also_ just works.\n\nIt's clearly a net win to only have to think about saturate/checked/wrap _once_ at the end of an expression instead of for every step in the middle. And LLVM will _already_ optimize down the size of your intermediates if you don't need them as big based on how it's used in the end: see https://rust.godbolt.org/z/c3fT4GcvE for an example, and note that while the rust code has `u128` multiplication and addition, it's optimized down to just `u32` operations.\n\nWhich means that, no\n\nchrefr:\n\n> Widening integer operations to i/u128 makes them way more expensive\n\nisn't the case because they're only widened if you actually need the extra precision.\n\n* * *\n\nThe actual \"downside\" here is that you have to specify the types of _mutable_ integers like loop accumulators, and things like `+=` basically stop working inside loops. But arguably that's a good thing -- if you're summing a whole bunch of `u8`s you probably didn't actually want a `u8` result -- and better overall than needing to worry about overflow at _every_ operation.\n\nIn languages like C it would be really painful because `for (i = 0; i < n; ++i)` wouldn't work, but obviously in Rust we spell that `for i in 0..n` where the `Range` type would just do the right thing, like it does today.\n\n(Constructing a `RangeInclusiveIter` from `start: Integer<A, B>` and `last: Integer<C, D>` would give you an `impl Iterator<Item = Integer<A, D>>`, for example. Where you'll notice that `B` and `C` are irrelevant, which is nice.)",
  "title": "Infinite precision intermediate arithmetic: how much would break?"
}