4

我正在尝试为学校项目实施 Erathostenes 筛,我决定使用位数组来实现。当我在搜索材料时,我遇到了这 3 个宏,它们完美地工作,但我无法真正阅读(理解)它们。

#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;

请您至少向我详细解释其中一个,我对 C 中的按位运算有非常基本的了解(基本上我知道它们“存在”)。

这是否适用于使用不同字节序的另一种架构?提前致谢。

4

3 回答 3

5

x是字符数组。i是位的索引。因为 everychar是 8 位,最后 3 位i定义了 char 中的位,其余位定义了数组中的 char。

i>>3将 i 向右移动 3 位,这样你就得到了告诉你哪个字符的部分,x[i>>3]包含由 . 索引的位的字符也是如此i

i&7i(since ) 的最后 3 位,所以它是 char 中位的索引。是一个 char(确实是 int,但在这种情况下你可以忽略差异),它的位由on 索引,其余位为 off。(位的掩码)710==11121<<(i&7)i

char&mask是检查位是否打开的常用方法。

char|=mask是转位的常用方法。

char&=~mask是关闭位的常用方法,如果mask是char,则~mask==mask^0xFF.

我不认为这些宏是字节序依赖的。(如果你x通过转换int[]*char,这是一个不同的故事)

于 2012-02-12T12:13:45.640 回答
4

首先,这些宏错误地假设CHAR_BIT == 8,i >> 3实际上是i / 8。(所以实际上这段代码应该说i / CHAR_BIT。)第一个表达式计算包含所需位的字节,因此是数组中的数组索引x(应该是一个数组unsigned char!)。

现在我们已经选择了正确的字节,即x[i >> 3](或x[i / CHAR_BIT]在您自己的更好的代码中),我们必须进行位摆弄。同样,i & 7真的很想成为i % CHAR_BIT,它只提取您的位计数的剩余部分,为您提供字节内的偏移量。

例子。用 请求第 44 位,i = 43并假设是 5,所以我们在第六个字节,并且是 3,所以我们正在查看第六个字节的第四位。CHAR_BIT = 8i / CHAR_BITi % CHAR_BIT

实际的位摆弄本身就是做通常的事情。例如,对给定位的测试使用适当的位模式(即第 th 位)执行逐位1 << kk;设置该位使用按位或,并且将其归零需要更多的参与(考虑一下!)。

于 2012-02-12T12:18:09.073 回答
-1
#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))
  • 始终在宏参数周​​围加上括号
  • 总是喜欢无符号类型进行位操作
  • (1u << CHAR_BIT) 对于 8 位平台是 256
  • ;最后一个宏之后有一个exra
于 2012-02-12T12:12:56.987 回答