将Int转换为Ints数组,指示C中位的位置

时间:2011-10-09 09:55:53

标签: c bit-manipulation built-in

因此,如果我有一个int,比如0000100101101001,那么它应该转换为像{0,3,5,6,8,11}这样的数组。我正在使用一个使用clz(计数前导零)和位掩码的复杂系统来实现它,但我怀疑应该存在更好的东西。

我使用的是i7并使用gcc,使用SIMD / SSE内置算法是件好事。

3 个答案:

答案 0 :(得分:3)

这个怎么样(应该对无符号整数有用):

while (x) {
    /* Store rightmost 1-bit in your array. */
    arr[i++] = x & (-x);

    /* Turn off rightmost 1-bit. */
    x = x & (x - 1);
}

我怀疑有更好的方法可以做到。

答案 1 :(得分:1)

您可以执行以下操作:

void bit2arr(int *result, size_t len, unsigned val) {
  int count = 0;
  while (val && len) {
    // add bit to array if needed
    if (val & 1) {
      *result++ = count;
      --len; // Don't overflow output
    }

    // Increment counter regardless
    ++count;

    // remove bit and bitshift
    val &= (~0 ^ 1);
    val >>= 1;
  }
}

一次取一位并将位置保存到数组(如果它不为零)。

我用它:

#include <stdio.h>
#include <string.h>

static const unsigned val = 2409;

int main() {
  int result[32];
  memset(result, 0, sizeof(result));

  bit2arr(result, 32, val);

  for (int i = 0; i < 32; ++i) {
    printf("%s%d", i ? ", " : "", result[i]);
  }
  printf("\n");
  return 0;
}

给出了:

  

0,3,5,6,8,11,0 ......

使函数返回结果数组的大小应该很容易。

答案 2 :(得分:1)

size_t bit2arr(char *result, unsigned val) {
size_t pos, cnt;

for (pos=cnt=0; val; val >>=1, pos++) {
   if (val & 1) result [cnt++] = pos;
   }

return cnt; /* number of 1 bits := number of valid positions in result[] */
}