让我们说x = 1110(12月14日)我想找到右边的第二个设置位0100(12月4个)
又一个例子,假设x = 10110010(十二月份为178),我想要右边的第三个设定位,即00100000(十二月三十二日)
如何找到它?有黑客吗?
答案 0 :(得分:3)
从数字中减去一个将清除设置的最低有效位,同时设置低于该值的位。与原始数字进行AND运算将留下一个等于原始数字的数字,除非原始最低设置位清零。该过程可以迭代N次以产生具有最低N个设置位的数字。由第N次迭代(如果有的话)改变的位将是原始中设置的第N个最低位。
答案 1 :(得分:1)
假设一个名为 number 的二进制补码有符号32位整数是输入(因此只计算for循环中的位0到30):
int number = (1 << 3) | 1; // this is the input, it can be whatever you like
int currentLsbCount = 0;
int desiredLsbCount = 2; // this is your n
int foundLsb = 0;
int foundLsbIndex = 0;
for (int i = 0; i < 31; i++)
{
int bit = (number >> i) & 1;
if (bit == 1)
{
++currentLsbCount;
}
if (currentLsbCount == desiredLsbCount)
{
foundLsb = number & (1 << i);
foundLsbIndex = i;
break;
}
}
foundLsb 将保持该值,如果输入为零,则为零; foundLsbIndex 将保存该位的索引。
据我所知,你必须迭代。没有比循环比特更快的方法。您可以添加一些跳过逻辑,但它不会改善最坏情况的时序。例如:
if ((number & ((1 << x) - 1)) == number)
{
// the bottom x bits are zero...
}
这会增加最坏情况下的操作次数。
答案 2 :(得分:1)
在VB.NET中,我可能会执行以下操作:
Private Function ReturnBit(input As Long, num As Long) As Long
Dim iResult As Long = 0 'Counts set bits.
Dim work As Long = input 'Working copy of input.
'Looping from the LSB to the MSB of a byte. Adjust for desired
'length, 15 for 2 bytes, 31 for 4 bytes, etc.
For i As Integer = 0 To 7
'If the working variable is 0, the input does not contain as
'many set bits as required. Return -1 if you wish.
If work = 0 Then Return 0
'Add the now LSB if 1, 0 otherwise.
iResult += (work And 1)
'iResult contains the number of set bits now. If this is
'the requested number, return this number. If you're just after
'the position, just return i instead. Instead of 2^i it could be
'more efficient to use 1<<i, but I'd rely on the compiler for
'this.
If iResult = num Then Return CLng(2 ^ i)
'Remove the LSB from the working copy.
work >>= 1
Next
Return 0 'Not enough set bits in input.
End Function