[英]C bit array macros, could anyone explain me how these work?
I'm trying to implement sieve of erathostenes for school project and I've decided to do so using bit arrays. 我正在尝试为学校项目实施erathostenes的筛选,我决定使用位数组来实现。 While I was searching for materials, I came across these 3 macros, they work flawlessly, but I can't really read(understand) them.
在我搜索材料时,我遇到了这三个宏,它们完美无缺,但我无法真正阅读(理解)它们。
#define ISBITSET(x,i) ((x[i>>3] & (1<<(i&7)))!=0)
#define SETBIT(x,i) x[i>>3]|=(1<<(i&7));
#define CLEARBIT(x,i) x[i>>3]&=(1<<(i&7))^0xFF;
Could you please explain to me at least one of them in detail, I have very basic knowledge about bitwise operations in C (basically I know they "exist"). 能否请你详细解释其中至少一个,我对C中的按位操作有基本的了解(基本上我知道它们“存在”)。
Will this work on another architecture using different endianness? 这会在另一个使用不同字节序的架构上工作吗? Thanks in advance.
提前致谢。
x
is array of chars. x
是字符数组。 i
is an index of bits. i
是位的索引。 since every char
is 8 bits, the last 3 bits of i
define the bit in the char, and the rest bits define the char in the array. 由于每个
char
都是8位,因此i
的最后3位定义了char中的位,其余位定义了数组中的char。
i>>3
shift i 3 bits to the right, so you get the part that tell you which char, so x[i>>3]
is the char that contain the bit indexed by i
. i>>3
右移3位,所以你得到的部分告诉你哪个字符,所以x[i>>3]
是包含由i
索引的位的字符。
i&7
is the last 3 bits of i
(since 7 10 ==111 2
), so it's the index of the bit in the char. i&7
是的最后3个比特i
(因为7 10 ==111 2
),所以它的焦炭中的所述位的索引。 1<<(i&7)
is a char (truly it's int, but in this context you can ignore the difference), that has the bit indexed by i
on, and the rest bits off. 1<<(i&7)
是一个char(真正的它是int,但在这个上下文中你可以忽略它的区别),它的位由i
开启,其余位关闭。 (the mask of the bit) (钻头的面具)
char&mask
is the common way to check if bit is on. char&mask
是检查位是否打开的常用方法。
char|=mask
is the common way to turn bit in. char|=mask
是转入的常用方法。
char&=~mask
is the common way to turn bit off, and if mask
is char, then ~mask==mask^0xFF
. char&=~mask
是关闭位的常用方法,如果mask
是char,则~mask==mask^0xFF
。
I don't think that these macros are endiannes-depend. 我不认为这些宏是依赖于endiannes的。 (if you got
x
by converting int[]
to *char
, it's a different story) (如果你通过将
int[]
转换为*char
得到x
,那就是另一个故事)
First off, those macros assume evilly that CHAR_BIT == 8
, and i >> 3
is actually i / 8
. 首先,那些宏假设
CHAR_BIT == 8
,而i >> 3
实际上是i / 8
。 (So really this code should say i / CHAR_BIT
.) This first expression computes the byte which contains your desired bit, and is thus the array index in your array x
(which should be an array of unsigned char
!). (所以这个代码应该说
i / CHAR_BIT
。)这个第一个表达式计算包含你想要的位的字节 ,因此是数组x
的数组索引(应该是unsigned char
的数组!)。
Now that we've selected the correct byte, namely x[i >> 3]
(or x[i / CHAR_BIT]
in your own, better code), we have to do the bit-fiddling. 现在我们已经选择了正确的字节,即
x[i >> 3]
(或者你自己的更好的代码中的x[i / CHAR_BIT]
),我们必须进行比特摆弄。 Again, i & 7
really wants to be i % CHAR_BIT
, and it extracts only the remainder of your bit count that gives you the offset within the byte. 同样,
i & 7
真的想成为i % CHAR_BIT
,它只提取你的位数的剩余部分,它给出了字节内的偏移量。
Example. 例。 Requesting the 44th bit with
i = 43
, and assuming CHAR_BIT = 8
, i / CHAR_BIT
is 5, so we're in the sixth byte, and i % CHAR_BIT
is 3, so we're looking at the fourth bit of the sixth byte. 请求第44位,
i = 43
,假设CHAR_BIT = 8
, i / CHAR_BIT
为5,所以我们在第六个字节, i % CHAR_BIT
是3,所以我们看第六个字节的第四个位。
The actual bit-fiddling itself does the usual stuff; 实际的比特摆弄本身就是常见的东西; eg testing for a given bit performs bit-wise AND with the appropriate bit pattern (namely
1 << k
for the k
th bit); 例如,测试给定位以适当的位模式执行逐位AND(即第
k
位的1 << k
); setting the bit uses bit-wise OR, and zeroing it requires something a tiny bit more involved (think about it!). 设置该位使用逐位OR,并将其归零需要更多涉及的东西(想一想!)。
#define ISBITSET(x,i) (((x)[(i) / CHAR_BIT] & (1u << ((i) % CHAR_BIT))) != 0)
#define SETBIT(x,i) (x)[(i) / CHAR_BIT] |= (1u << ((i) % CHAR_BIT);
#define CLEARBIT(x,i) (x)[(i) / CHAR_BIT] &= ~(1u << ((i) % CHAR_BIT))
;
;
after the last macro
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.