authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-10-30 19:30:02+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-11-01 17:06:14-05:00
log445d808bae4b9a2ff1c7a56a4ebff64ae848f46c
tree62ad307aaf5772c2066aed44a3bfe54f479afbb7
parent2e1cef75086a0b606fd8f1f7a0cda4ab2f0b7a49

std: Fix early overflow in time calculation

Closes #6867

1 files changed, 11 insertions(+), 2 deletions(-)

lib/std/time.zig+11-2
......@@ -242,15 +242,24 @@ pub const Timer = struct {
242242
243243 fn nativeDurationToNanos(self: Timer, duration: u64) u64 {
244244 if (is_windows) {
245 return @divFloor(duration * ns_per_s, self.frequency);
245 return safeMulDiv(duration, ns_per_s, self.frequency);
246246 }
247247 if (comptime std.Target.current.isDarwin()) {
248 return @divFloor(duration * self.frequency.numer, self.frequency.denom);
248 return safeMulDiv(duration, self.frequency.numer, self.frequency.denom);
249249 }
250250 return duration;
251251 }
252252};
253253
254// Calculate (a * b) / c without risk of overflowing too early because of the
255// multiplication.
256fn safeMulDiv(a: u64, b: u64, c: u64) u64 {
257 const q = a / c;
258 const r = a % c;
259 // (a * b) / c == (a / c) * b + ((a % c) * b) / c
260 return (q * b) + (r * b) / c;
261}
262
254263test "sleep" {
255264 sleep(1);
256265}