I'm trying to avoid long long
s and integer overflow in some calculations, so I came up with the function below to calculate (a * b) / c
(order is important due to truncating integer division).
unsigned muldiv(unsigned a, unsigned b, unsigned c)
{
return a * (b / c) + (a * (b % c)) / c;
}
Are there any edge cases for which this won't work as expected?
EDITED: This is correct for a superset of values for which the original obvious logic was correct. It still buys you nothing if c
> b
and possibly in other conditions. Perhaps you know something about your values of c
but this may not help as much as you expect. Some combinations of a
, b
, c
will still overflow.
EDIT: Assuming you're avoiding long long
for strict C++98 portability reasons, you can get about 52 bits of precision by promoting your unsigned
to double
s that happen to have integral values to do the math. Using double
math may in fact be faster than doing three integral divisions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With