Note. The following code snippets only work when both operands are positive. I omitted any handling of negative values, because the results of x % y , when one or both operands are negative, differ between different languages ββand platforms. In the general case, you can simply calculate abs(x) % abs(y) and then do some conversion of the result.
The easiest way to calculate x % y using only addition and subtraction is to simply subtract y until the remaining value is less than y :
int mod_basic(int x, int y) { int result = x; while (result >= y) result -= y; return result; }
However, this approach is rather inefficient. A more complex but faster method is to use binary long division . This is similar to regular long division, with the exception of the binary result, at each step - 0 or 1 instead of 0..9 . The basic approach to computing x % y with BLD is as follows:
int mod_bld(int x, int y) { int modulus = x, divisor = y; while (divisor <= modulus && divisor <= INT_MAX/2) divisor <<= 1; while (modulus >= y) { while (divisor > modulus) divisor >>= 1; modulus -= divisor; } return modulus; }
One of those found above: divisor <= INT_MAX/2 must stop the overflow in divisor <<= 1 when x > MAX_INT/2 .
Additionally, divmod , which gives you both a factor and a module in one calculation, looks almost accurate:
void divmod(int x, int y, int *div, int *mod) { int quotient = 0, modulus = x, divisor = y; while (divisor <= modulus && divisor <= INT_MAX/2) divisor <<= 1; while (modulus >= y) { while (divisor > modulus) { divisor >>= 1; quotient <<= 1; } modulus -= divisor; quotient++; } while (divisor != y) { quotient <<= 1; divisor >>= 1; } *div = quotient; *mod = modulus; }
Finally, note that if y is a power of 2, you can cheat. In this case, x % y is just x & (y - 1) .