313. div_duration_f64 — Your Progress Bar Sat at 0% Because as_secs() Truncated First
Dividing two Durations with as_secs() is integer division — 1.5s of 60s truncates to 0, and your progress bar never moves.
The obvious way to compute “how far along are we” divides seconds by seconds:
| |
as_secs() returns u64, so the sub-second part is gone before the division even runs, and the quotient truncates to zero on top of that. Switching to as_millis() just moves the truncation point; switching both sides to as_secs_f64() works but says nothing about intent.
Divide the durations directly
div_duration_f64 (stable since 1.80) divides one Duration by another and gives back the ratio as a float, sub-second precision included:
| |
It reads in the same direction as the math: elapsed.div_duration_f64(total) is elapsed ÷ total. The same shape works for any “how many times does this fit” question — like a benchmark speedup:
| |
Two things worth knowing: there’s a div_duration_f32 twin if you’re feeding a graphics API, and dividing by Duration::ZERO follows float semantics — you get inf, not a panic. That’s one less edge case than the integer route, where total.as_secs() being zero would have crashed the division outright.
Like bite 311 and bite 312, the theme is the same: Duration already has a method for the math you’re about to do by hand — and the hand-rolled version is where the bugs live.