252. Wrapping<T> — Modular Arithmetic Without the .wrapping_add() Noise
Hash functions, checksums, and PRNGs want arithmetic mod 2^n — but writing .wrapping_mul() on every single operation buries the math. std::num::Wrapping<T> puts the semantics in the type so you can use plain operators again.
Method-call soup
In wrap-heavy code every operation needs the method form, or debug builds panic on overflow:
| |
One call is fine. But real hash/PRNG code chains them — x.wrapping_mul(a).wrapping_add(c) — and the actual formula disappears under the method names. Forget one and a debug build panics while release silently wraps.
Wrapping moves the choice into the type
Wrap the values once; every operator on them wraps from then on:
| |
*, +, -, <<, the assign forms, even unary - — all defined to wrap, in every build profile. .0 unwraps back to the plain integer at the boundary.
| |
Declare intent once, not per call
The win is the same one Saturating<T> gives you (bite 167): overflow behavior is a property of the data, declared once, instead of a per-callsite decision you can fumble. The type keeps you honest, too — you can’t accidentally mix a wrapping value into checked arithmetic without an explicit .0.
Stable since Rust 1.0, Copy, zero-cost: Wrapping<u32> compiles to exactly the same instructions as the wrapping_* calls. If a function is more math than method names, wrap the inputs and let the operators speak.