I’m trying to avoid long longs 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>band possibly in other conditions. Perhaps you know something about your values ofcbut this may not help as much as you expect. Some combinations ofa,b,cwill still overflow.EDIT: Assuming you’re avoiding
long longfor strict C++98 portability reasons, you can get about 52 bits of precision by promoting yourunsignedtodoubles that happen to have integral values to do the math. Usingdoublemath may in fact be faster than doing three integral divisions.