I want to create a method which given a number n and the number 16 and applies the modulus operator to them (n % 16)
. The thing which makes it hard for me is that I need to not use any of math operators (+, -, /, *, %).

- 15,394
- 19
- 63
- 95
-
3In general this won't be possible, but specifically for 16 (or powers of two) you can just mask, `n & 15`. Also fails on negative numbers – kalhartt Dec 14 '13 at 17:54
-
2@kalhartt - assuming the integer representation is twos complement, and that there are no undefined behaviour issues, `n & 15` will give the correct modulous even for negative `n` - but not necessarily the same value as `n % 16`. Remainders are defined relative to division, so the result depends on the rounding used for the division, but modulous results are always non-negative. `-1 mod 16 == 15`, though `-1 rem 16` may be 15 or -1. Sorry, I can't be more specific as I don't know Ruby. – Dec 14 '13 at 18:08
-
Why can't you use arithmetic operators? Why can't you simply use `%` and get on with more productive work? – mu is too short Dec 14 '13 at 19:01
-
Sure I would use % if it for work, but this is a coding challenge I stumbled at. – Wazery Dec 14 '13 at 19:04
-
@Steve314 can you explain? If we assume bit length much greater than the mask, then you can see `-5 & 15` is `11` which is neither 10 for division rounding to -inf nor 5 for division rounding to zero. – kalhartt Dec 14 '13 at 19:30
-
1Nevermind, I'm an idiot. Just forgot its off by one. – kalhartt Dec 14 '13 at 19:38
-
@kalhartt - yes, you're off by one. For division rounding to -inf, it's `-5 rem 16 == 11` that equates to `-5 & 15 == 11`. – Dec 14 '13 at 21:13
2 Answers
Since 16
is 2^4
you can obtain the same result by truncating the value to the 4 least significant bits.
So:
x & 0xF
is equivalent to x % 16
This is valid just because you are working with a power of two.

- 131,802
- 30
- 241
- 343
The key here is that 16 is a power of two, and so you can exploit the fact that computers utilise binary representations to achieve what you want with a bitwise operator.
Consider how multiples of 16 look when represented in binary:
0001 0000 // n = 16, n%16 = 0
0010 0000 // n = 32, n%16 = 0
0011 0000 // n = 48, n%16 = 0
0100 0000 // n = 64, n%16 = 0
Now take a look at some numbers for which n % 16
would be non-zero:
0000 0111 // n = 7, n%16 = 7
0001 0111 // n = 23, n%16 = 7
0010 0001 // n = 33, n%16 = 1
0100 0001 // n = 65, n%16 = 1
Notice that the remainder is simply the least significant 4 bits (nibble) - therefore we simply need to construct a bitwise expression that will keep these bits intact, whilst masking all other bits to zero. This can be achieved by performing a bitwise AND operation with the binary value 15:
x = n & 0xF

- 9,755
- 1
- 28
- 32
-
1A group of 4 bits is traditionally called a nibble, a byte is (usually) 8 bits. – Dec 14 '13 at 18:12