我在 C: 中有一个无符号字符数组
unsigned char array[] = { 0xF0, 0xCC, 0xAA, 0xF0};
/* Represented as binary: 11110000 11001100 10101010 11110000 */
我想从这个数组中提取最后 N 位并将它们存储在一个整数中。例如,如果我想提取最后 5 位,结果应该是:
int i = 32; /* Represented as binary: 10000 */
我尝试使用 BIGNUM 库,但我发现它有点矫枉过正,而且对于这个目的来说有点慢。在 C 中是否有更有效的方法来实现这一目标?
附代码:
unsigned char array[] = { 0xF0, 0xCC, 0xAA, 0xF0};
int i = 0;
int j;
int totalBits = sizeof(array) * 8;
int startBit = totalBits - 5;
for (j = startBit; j < totalBits; j++)
{
i = i << 1;
i = i | (array[j] & 1);
}
勇敢的努力!感谢您展示您的尝试。
我在您的版本中添加了一些评论:
unsigned char array[] = { 0xF0, 0xCC, 0xAA, 0xF0};
int i = 0;
int j;
int totalBits = sizeof(array) * 8; // currently meaning 32
int startBit = totalBits - 5; // meaning 27 where '5' is the magic number wanted
for (j = startBit; j < totalBits; j++)
{
i = i << 1;
i = i | (array[j] & 1); // Oops! there is no array[27]! Top element is array[3]!
}
下面是一个似乎有效的版本的草稿:
int main(void) {
unsigned char arr[] = { 0xF0, 0xCC, 0xAA, 0xF0 }; // Your array (add more! Try it out!)
union { // providing for up to N = 64bits (on my system)
unsigned char c[8];
unsigned long l;
} foo;
foo.l = 0; // initialise
size_t sz = sizeof arr / sizeof arr[0]; // source byte count
size_t n = 0; // destination byte count
// wastefully copy as many bytes as are available until 'foo' is a full as possible
// Notice the 'endian-ness' of index n going from 0 to 8.
// Other hardware could change this to count downward, instead.
for( size_t i = sz; i && n < sizeof foo; ) {
foo.c[ n++ ] = arr[ --i ]; // grab one byte
printf( "%x\n", foo.l ); // debugging
}
int N = 5;
foo.l &= (1<<N)-1; // Mask off the low order N bits from that long
printf( "%x\n", foo.l );
return 0;
}
希望这有帮助。
后期警告:在这段代码中,
N
的最大值是63
...应该添加检查N
不超过累加器foo
的宽度,并且如果N
恰好是该数字,绕过移位和掩码操作...
PS:在进行位操作时,使用
unsigned
数据类型通常更安全。一些 C 实现显然反对符号位被不当修改。