我想在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
是否有预定义的算法?使用按位运算符?
答案 0 :(得分:2)
给定char *
数组,您可以轻松实现运算符set
和get
分别设置和检索第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(=零与非零)值。