让a
成为unsigned int
:
unsigned int a = 188; // 10111100
是否有一个内置函数可以获得打开的小位?例如:在a
情况下,应返回2
,因为第一位和第二位零,但第三位是一。
// 10111100
// ^
// |-- Minor bit turn on
我正在使用GCC和C99标准。
答案 0 :(得分:3)
简单明了的解决方案:
#include <stdio.h>
int minor_bit(unsigned int x);
int main() {
unsigned int a = 188;
printf("%d\n", minor_bit(a));
return 0;
}
int minor_bit(unsigned int x) {
unsigned int i;
if (x == 0)
return -1;
for (i = 0; !(x & 1U << i); i++);
return i;
}
答案 1 :(得分:2)
这不是内置的,但可以工作......
鉴于最低1位和人口计数(Ones Count)算法,将它们组合起来构造一个尾随零计数是非常简单的(正如Joe Bowbeer指出的那样):
unsigned int
tzc(register int x)
{
return(ones((x & -x) - 1));
}
其中ones可以是32位:
unsigned int
ones32(register unsigned int x)
{
/* 32-bit recursive reduction using SWAR...
but first step is mapping 2-bit values
into sum of 2 1-bit values in sneaky way
*/
x -= ((x >> 1) & 0x55555555);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >> 4) + x) & 0x0f0f0f0f);
x += (x >> 8);
x += (x >> 16);
return(x & 0x0000003f);
}
答案 2 :(得分:2)
我相信这会成功。部分功劳归the solution。
int validate(unsigned value) {
int count = 0;
for (int i = 0; i < 8*sizeof(value); i++) { // 32 bits in unsigned int
int bit = (value >> i) & 1;
if (bit == 1) {
break;
} else {
count++;
}
}
return count;
}
答案 3 :(得分:2)
最多可达64位。
static signed char f(uint64_t x)
{
static const signed char p[] = { -1, 0, 1, 39, 2, 15, 40, 23, 3, 12,
16, 59, 41, 19, 24, 54, 4, 0, 13, 10, 17, 62, 60, 28, 42, 30, 20,
51, 25, 44, 55, 47, 5, 32, 0, 38, 14, 22, 11, 58, 18, 53, 63, 9,
61, 27, 29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56,
7, 48, 35, 6, 34, 33, };
return p[(x & -x) % 67];
}
目前尚不清楚应该从0返回什么,所以我用了-1。显然,这可以改变。
答案 4 :(得分:1)
int minor(int value){
int i=0;
//Edge case (but could be fairly common)
if (value == 0) {
return -1;
}
//Continuously left-shifts 1 and ANDs it with input value
//in order to find the first occurrence of the rightmost bit != 0
while ((value & ( 1 << i )) == 0) {
i++;
}
return i;
}
答案 5 :(得分:1)
一种适度且高度便携的解决方案
unsigned
为64位时最多16个循环。使用N位int
进行少于N次移位。
int MinorBit(unsigned x) {
if (x == 0)
return -1; // special case, adjust as needed.
int m = 0;
// Search by char
while ((x & ((1u << CHAR_BIT) - 1)) == 0) {
x >>= CHAR_BIT;
m += CHAR_BIT;
}
// Search by bit
while ((x & 1) == 0) {
x >>= 1;
m++;
}
return m;
}
答案 6 :(得分:1)
是。由于您使用的是GCC,因此可以使用__builtin_ctz系列内置函数来追踪零计数,
int __builtin_ctz (unsigned int x);
取自http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html。
例如,
2 == __builtin_ctz(188)
警告:对于输入0,结果是未定义的。因此,它的使用可能需要加以保护,因此:
int safe_ctz(unsigned int x){
return x ? __builtin_ctz(x) : 32;
}
这种内置的优势在于,对于某些目标,GCC将其转换为单个指令,例如x86上的BSF。