常见位操作:获取与设置数位

186 阅读2分钟

这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战

常见位操作:获取与设置数位

了解以下操作至关重要,但不要一味死记硬背,死记硬背会导致犯一些无法修复的错误。相反地,只需理解如何实现这些方法即可,从而确保在实现的过程中只是犯一些小错误。

获取数位

该方法将1左移i位,得到形如00 010 000的值。接着,对这个值与num执行“位与”操作(AND),从而将i位之外的所有位清零。最后,检查该结果是否为0。不为0说明i位为1,否则,i位为0。

设置数位

setBit先将1左移i位,得到形如00 010 000的值。接着,对这个值和num执行“位或”操作(OR),这样只会改变i位的数值。该掩码i位除外的位均为0,故而不会影响num的其余位。

清零数位

该方法与setBit刚好相反。首先,将数字00 010 000取反进而得到类似于11 101 111的数字。接着,对该数字和num执行“位与”操作(AND)。这样只会清零num的第i位,其余位则保持不变。

如果要清零最高位至第i位所有的数位(包括最高位和第i位),需要创建一个第i位为1(1<<i)的掩码。然后,将其减1并得到一串第一部分全为0,第二部分全为1的数字。之后我们将目标数字与该掩码执行“位与”操作(AND),即得到只保留了最后i位的数字。

如果要清零第i位至第0位的所有的数位(包括第i位和第0位),使用一串1构成的数字(即-1)并将其左移i+1位,如此便得到一串第一部分全为1,第二部分全为0的数字。

更新数位

将第i位的值设置为v,首先,用诸如11 101 111的掩码将num的第i位清零。然后,将待写入值v左移i位,得到一个i位为v但其余位都为0的数。最后,对之前取得的两个结果执行“位或”操作,v为1则将numi位更新为1,否则该位仍为0。