根据偏移量和长度在数组中设置bin字段

时间:2018-05-04 09:56:15

标签: c algorithm bit-manipulation bitwise-operators

我想在C中开发一个函数,它在数组中从给定的偏移量开始设置一个二进制字段,并以给定的长度结束。

例如,我的二进制数组是:

01101011 10010101 11001011 11010001 11000101 00101011

用于set的缓冲区:

10011001 01011011 10100010

因此,如果offset = 5且length = 7,则结果为

我们将从偏移量5开始在二进制缓冲区中设置缓冲区中的第一位(1001100):

01101100 11000101 11001011 11010001 11000101 00101011
     ^      ^
     |      |__End of set field (len=7)
   offset=5   

是否有预定义的算法?使用按位运算符?

1 个答案:

答案 0 :(得分:2)

给定char *数组,您可以轻松实现运算符setget分别设置和检索第i位:

void set(char *a, int position, int value) {
     int byte = position >> 3;
     int bit = 1 << (position & 0x07); // 00000001b to 10000000b
     a[byte] = value ? 
           a[byte] | bit :  // on
           a[byte] & ~bit;  // off
}

int get(char *a, int position) {
     return a[position>>3] & (1 << (position&0x07)) ? 1 : 0;
}

使用编译器内在函数同时获得除法和模数可以稍快一些,并且可能有一些按位技巧来避免'set'中的分支 - 但希望这段代码能够传达操作的要点。 / p>

实现所需的函数本质上是我的set函数中代码的扩展,其中不是只触摸一位,而是继续直到用完要修改的位,从指示的偏移量开始。

修改:从this answer添加按位技巧以从set中移除分支:

void set(char *a, int position, int value) {
     int byte = position >> 3;
     int offset = position & 0x07);
     a[byte] = (a[byte] & ~(1<<offset)) | (value<<offset);
}

请注意,此版本要求value为0或1;以前的版本可以使用任何false或true(=零与非零)值。