Last active
September 1, 2024 21:55
-
-
Save jspohr/3dc4f00033d79ec5bdaf67bc46c813e3 to your computer and use it in GitHub Desktop.
Avoid overflow when converting time to microseconds
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Taken from the Rust code base: https://github.com/rust-lang/rust/blob/3809bbf47c8557bd149b3e52ceb47434ca8378d5/src/libstd/sys_common/mod.rs#L124 | |
// Computes (value*numer)/denom without overflow, as long as both | |
// (numer*denom) and the overall result fit into i64 (which is the case | |
// for our time conversions). | |
int64_t int64MulDiv(int64_t value, int64_t numer, int64_t denom) { | |
int64_t q = value / denom; | |
int64_t r = value % denom; | |
// Decompose value as (value/denom*denom + value%denom), | |
// substitute into (value*numer)/denom and simplify. | |
// r < denom, so (denom*numer) is the upper bound of (r*numer) | |
return q * numer + r * numer / denom; | |
} | |
int64_t timeInMicros() { | |
// Get time and frequency | |
LARGE_INTEGER time; | |
QueryPerformanceCounter(&time); | |
LARGE_INTEGER frequency; | |
QueryPerformanceFrequency(&frequency); | |
// Convert to microseconds | |
const int64_t microsPerSecond = 1000000LL; | |
int64_t micros = int64MulDiv(time.QuadPart, microsPerSecond, frequency.QuadPart); | |
return micros; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment