You can first divide a by c, and get a division reminder and multiply the reminder by b before dividing it by c. Thus, you only lose data in the last section, and you get the same result as 64-bit division.
You can rewrite the formula as follows (where \ is an integer division):
a * b / c = (a / c) * b = (a \ c + (a % c) / c) * b = (a \ c) * b + ((a % c) * b) / c
After making sure that a> = b, you can use large values ββbefore overflowing:
uint32_t muldiv(uint32_t a, uint32_t b, uint32_t c) { uint32_t hi = a > b ? a : b; uint32_t lo = a > b ? b : a; return (hi / c) * lo + (hi % c) * lo / c; }
Another approach would be the addition and subtraction of cycles instead of multiplication and division, but this, of course, works a lot more:
uint32_t muldiv(uint32_t a, uint32_t b, uint32_t c) { uint32_t hi = a > b ? a : b; uint32_t lo = a > b ? b : a; uint32_t sum = 0; uint32_t cnt = 0; for (uint32_t i = 0; i < hi; i++) { sum += lo; while (sum >= c) { sum -= c; cnt++; } } return cnt; }
Guffa source share