Assuming that uint
is the largest integral type on my fixed-point platform, I have:
uint func(uint a, uint b, uint c);
Which needs to return a good approximation of a * b / c
.
The value of c
is greater than both the value of a
and the value of b
.
So we know for sure that the value of a * b / c
would fit in a uint
.
However, the value of a * b
itself overflows the size of a uint
.
So one way to compute the value of a * b / c
would be:
return a / c * b;
Or even:
if (a > b)
return a / c * b;
return b / c * a;
However, the value of c
is greater than both the value of a
and the value of b
.
So the suggestion above would simply return zero.
I need to reduce a * b
and c
proportionally, but again - the problem is that a * b
overflows.
Ideally, I would be able to:
- Replace
a * b
withuint(-1)
- Replace
c
withuint(-1) / a / b * c
.
But no matter how I order the expression uint(-1) / a / b * c
, I encounter a problem:
uint(-1) / a / b * c
is truncated to zero because ofuint(-1) / a / b
uint(-1) / a * c / b
overflows because ofuint(-1) / a * c
uint(-1) * c / a / b
overflows because ofuint(-1) * c
How can I tackle this scenario in order to find a good approximation of a * b / c
?
Edit 1
I do not have things such as _umul128
on my platform, when the largest integral type is uint64
. My largest type is uint
, and I have no support for anything larger than that (neither on the HW level, nor in some pre-existing standard library).
My largest type is uint
.
Edit 2
In response to numerous duplicate suggestions and comments:
I do not have some "larger type" at hand, which I can use for solving this problem. That is why the opening statement of the question is:
Assuming that
uint
is the largest integral type on my fixed-point platform
I am assuming that no other type exists, neither on the SW layer (via some built-in standard library) nor on the HW layer.