Getting the modulus of a number can be easily done without the modulus operator or divisions, if your operand is a power of 2. In that case, the following formula holds:
If you want to get the modulus of dividing by a denominator d
such that d = (1 << e) - 1
where e
is some exponent, you can use the fact that the binary expansion of 1/d
is a repeating fraction with bits set every e
digits. For example, for e = 5
, d = 31
, and 1/d = 0.0000100001...
.
Similar to rici’s answer, this algorithm effectively computes the sum of the base-(1 << e)
digits of a
:
uint16_t mod31(uint16_t a) {
uint16_t b;
for (b = a; a > 31; a = b)
for (b = 0; a != 0; a >>= 5)
b += a & 31;
return b == 31 ? 0 : b;
}
You can unroll this loop, because the denominator and the number of bits in the numerator are both constant, but it’s probably better to let the compiler do that. And of course you can change 5
to an input parameter and 31
to a variable computed from that.