For unsigned int x, is it possible to calculate x % 255 (or 2^n - 1 in general) using only the following operators (plus no loop, branch or function call)?
!
, ~
, &
, ^
, |
, +
, <<
, >>
.
Yes, it's possible. For 255, it can be done as follows:
unsigned int x = 4023156861;
x = (x & 255) + (x >> 8);
x = (x & 255) + (x >> 8);
x = (x & 255) + (x >> 8);
x = (x & 255) + (x >> 8);
// At this point, x will be in the range: 0 <= x < 256.
// If the answer 0, x could potentially be 255 which is not fully reduced.
// Here's an ugly way of implementing: if (x == 255) x -= 255;
// (See comments for a simpler version by Paul R.)
unsigned int t = (x + 1) >> 8;
t = !t + 0xffffffff;
t &= 255;
x += ~t + 1;
// x = 186
This will work if unsigned int
is a 32-bit integer.
EDIT: The pattern should be obvious enough to see how this can be generalized to 2^n - 1
. You just have to figure out how many iterations are needed. For n = 8
and a 32-bit integer, 4 iterations should be enough.
EDIT 2:
Here's a slightly more optimized version combined with Paul R.'s conditional subtract code:
unsigned int x = 4023156861;
x = (x & 65535) + (x >> 16); // Reduce to 17 bits
x = (x & 255) + (x >> 8); // Reduce to 9 bits
x = (x & 255) + (x >> 8); // Reduce to 8 bits
x = (x + ((x + 1) >> 8)) & 255; // Reduce to < 255
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With