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

set bin field in an array based on offset and length

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

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

01101011 10010101 11001011 11010001 11000101 00101011

用于设置的缓冲区:

10011001 01011011 10100010

所以如果偏移量 = 5 且长度 = 7,结果将是

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

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

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

给定 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' 中分支 - 但希望这段代码传达了要点操作。

实现你想要的功能本质上是我的 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;以前的版本适用于任何假或真(=零与非零)值。