需要帮助解释在 wiss 代码中使用 / 和 % 的位操作

Need help explaining bit manipulation with / and % in wiss code

setbit(mapptr, pos)
register unsigned char  *mapptr;
register int    pos;
{
/* adjust word pointer and bit offset (pos) */

    /************** FROM HERE ****************/
    mapptr += pos / BITSPERBYTE;
    pos %= BITSPERBYTE;
    /*************** TO HERE ***************/

*mapptr |= 1 << pos;        /* set bit */
 }

wiss文件系统中有位操作代码我不明白(用一对注释标记)。

为什么要把pos分成BITPERBYTE(定义为8),把pos运算成BITPERBYTE

您想在位图中设置位 X。如果一个字节有八位,

  • 位 X 将位于字节 X/8 中(基于 0 的整数数学 => 向零舍入,即向下舍入为正数 pos
  • 它将是该字节的第 X%8 位(即删除我们用于在此计算中查找字节的组件)

所以

mapptr += pos / BITSPERBYTE;

计算我们要设置的位的字节偏移量,将其添加到指针,然后

pos %= BITSPERBYTE;

修改pos以索引我们要设置的那个字节的位;然后 1 << pos 生成该位,我们 'or' 将其放入我们选择的字节中:

*mapptr |= 1 << pos;        /* set bit */

代码 "packs" 以位 0..7 进入字节 0、8..15 进入字节 1、16..23 进入字节 2 等方式将位转换为字节在。如果你将一个位数除以 8 并去掉余数,你将得到相应的字节数:

int byteNumber = bitNumber / BITSPERBYTE;

您的代码片段将 byteNumber 添加到 mapptr,这相当于通过指针算法对字节数组进行索引。

% 8的结果与获得最后三位相同,即从 0 到 7 的数字,包括在内。这是相应字节内的位数:

int bitInByte = bitNumber % BITSPERBYTE;

% 的结果始终在 0..BITSPERBYTE-1 范围内。

注意:您的代码是 pre-ANSI,请考虑使用过去几十年的标准语法重写它,并更改 pos 的类型到 unsigned:

void setbit(unsigned char *mapptr, unsigned int pos) {
    mapptr += pos / BITSPERBYTE;
    pos %= BITSPERBYTE;
    *mapptr |= 1 << pos;
}