82. isqrt — Integer Square Root Without Floating Point
(n as f64).sqrt() as u64 is the classic hack — and it silently gives the wrong answer for large values. Rust 1.84 stabilized isqrt on every integer type: exact, float-free, no precision traps.
The floating-point trap
Converting to f64, calling .sqrt(), and casting back is the go-to pattern. It looks fine. It isn’t.
| |
f64 only has 53 bits of mantissa, so for u64 values above 2^53 the conversion loses precision before you even take the square root.
The fix: isqrt
| |
It’s defined on every integer type — u8, u16, u32, u64, u128, usize, and their signed counterparts — and always returns the exact floor of the square root. No casts, no rounding, no surprises.
Signed integers too
| |
Use checked_isqrt on signed types when the input might be negative — it returns Option<T> instead of panicking.
When you’d reach for it
Perfect-square checks, tight loops over divisors, hash table sizing, geometry on integer grids — anywhere you were reaching for f64::sqrt purely to round down, reach for isqrt instead. It’s faster, exact, and one character shorter.