Is it possible to rewrite modulo (2^n - 1) using bitwise and restricted operators

两盒软妹~` 提交于 2019-12-03 17:02:57

问题


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)?

!, ~, &, ^, |, +, <<, >>.


回答1:


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



回答2:


Just create an array with all the values (only either need 32 or 64 entries (i.e. 128 or 512 bytes). Then just do a look up.




回答3:


Sure. Just get out one of your old computer architecture textbooks and refresh your memory on boolean algebra. A CPU's ALU does it with ANDs and ORs; you can, too.

But why?

An academic exercise? Homework? Curiousity?



来源:https://stackoverflow.com/questions/7709651/is-it-possible-to-rewrite-modulo-2n-1-using-bitwise-and-restricted-operator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!