Question: generate mask indicating leftmost 1 in X. Assume W = 32.
For example 0xff00-> 0x8000, and 0x6600 --> 0X4000
Required. The code can contain up to 15 Arithmetic Operators, bitwise operations, and logical operations.
Method 1:
int leftmost_one(unsigned x){int result=x;if(0!=x){while(x){result=x;x=x&(x-1);}}return result;}
The estimation of this Code is a common solution. The time complexity O (N) and space complexity O (1) obviously do not meet the requirements, although only one bitwise operation is added to one arithmetic operation in a single loop, if all 32 bits are 1, 32*2 operators are required.
Method 2:
int leftmost_one1(unsigned x){if(x>(1<<31)){x=0x80000000;}if(0!=x&&x<(1<<31)){x=x|(x>>1);x=x|(x>>2);x=x|(x>>4);x=x|(x>>8);x=x|(x>>16);x+=1;x=x>>1;}return x;}
I used to use a program with only one entry and one exit, just like the above, but I had to change it to the following to meet the 15 restriction:
int leftmost_one1(unsigned x){if(x==0){return x;}if(x>(1<<31)){return 0x80000000;}x=x|(x>>1);x=x|(x>>2);x=x|(x>>4);x=x|(x>>8);x=x|(x>>16);x+=1;x=x>>1;return x;}
This code was completed after I thought about it for a long time. Time complexity O (1) and space complexity O (1). I personally feel that it is relatively elegant. The basic principle is as follows:
Assume that X is represented by 8 bits (0100 1010). In the end, the first 5 results of the code above are 0111 1111. Then, add 1 and move one unit to the right to obtain the required mask. In fact, the idea of this question is to keep up with the principle of a question. If you are not familiar with it, you can refer to the analysis in the previous article.