Problem: The Mask of the binary number (which is limited to a non-negative integer) is required. For example, if the value of decimal number 5 is written as 101 in binary format, the mask is 111, that is, the number of decimal digits 7, the mask for the decimal number 23 (10111) is 31 (11111 ).
Any non-negative integer m is satisfied, and the mask is M. For example, the mask of 5 is. Therefore, our idea is to find this K value to find the mask.
Method 1: Directly obtain.
Directly obtain the mask using the logarithm operation of the library function.
Maskofnumber(Number)
Return (1 <k)-1)
The above code is simple and clear, but what if the library function cannot be used?
Method 2:
Obviously, we can start from 1 and use the shift operation to continuously perform T = 1 <K (k = 0, 1, 2, 3 ...... n) operation until a T satisfies m <t, the t-1 is the mask we require. Based on this idea, you can quickly write the corresponding code. I will not post the code here.
Method 3:
Considering the nature of this problem, what we need is to find out where the highest bit of the binary number is. As long as we find 1 of the highest bit, we can easily find the mask. Alternatively, if you cannot directly obtain the first of the highest bits, but you can obtain all the positions of 1 in the binary number. The disadvantage of method 2 is that, no matter where the highest bit of the binary number is, we need to perform a shift operation on each low bit. For example, if the binary number is 1000 (expressed in binary ), the mask value can be obtained only after four shifts are performed according to method 2. So, is the algorithm simplified only by considering the location of the binary number 1? The answer is yes. Contact me in the previous blog to find the number of 1 in the binary number and make a slight modification to the algorithm to obtain the mask algorithm.
uint MaskOfNumber(uint number) { uint mask = 0; while (number != 0) { mask = (number - 1); number &= mask; } return (mask<<1)|1; }
Method 4:
Method 3 only processes the bits of all 1 in the binary number, so it is more efficient than method 2. However, this solution is not good enough for us to solve the mask problem, because we are concerned about the highest bit 1, however, the result of the low one-on-one problem does not matter much. In other words, let's look for the position of the highest bit 1 of a binary number. Okay. In all the beautiful search algorithms, the binary method leaves a simple and efficient impression on me. So try the binary method.
If the binary number is divided into two parts from the middle, how can we determine the part where the highest bit 1 is? Obviously, if the high part is 0, the highest bit must be in the low part, then adjust the high endpoint of the second part, and then perform a binary search for the lower part, the operation is performed cyclically until a high part contains only one 1, that is, the query ends.
// Bitslength is the length of the data type. Here it is the length of uint, Which is 32 uint maskofnumber (uint number, uint bitslength) {If (number = 0) Return (~ (Uint) 0); uint high = bitslength-1; uint low = 0; uint mid = 0; while (high> = low) {mid = (high + low) /2; uint T = number> (INT) Mid; If (t = 1) break; else if (T> 1) Low = Mid + 1; else high = mid-1;} // generate the mask value uint mask = (~ (Uint) 0) >>( (INT) (bitslength-mid-1); Return mask ;}
For the execution speed, the best average performance of these methods in C # Is method 1 and Method 4, followed by method 3, and the worst is method 2. That is, 1, 4> 3> 2
Finally, you are welcome to discuss other implementations.