对变量的第 n 位(bit)置 1、清零和取反
位-置 1(bit-set)
用|操作符来位置 1,
variable |= 1UL << n; // 1UL--------无符号长整型1 // 如果没有UL后缀,则系统默认为 int类型,即,有符号整形。
这段代码是将 variable 的第n位赋为 1。
注意,如果 variable 的长度大于unsigned long(4字节),就需要把1UL换成1ULL(8字节)。
位-置 0(bit-clear)
用&操作符来清零一个位,
variable &= ~(1UL << n);
将 variable 的第 n 位赋为 0。
位-置反(bit-toggle)
用^操作符来置反一个位(即 0 变 1,1 变 0),
variable ^= 1UL << n;
将 variable 的第 n 位置反。
位-检查(bit-check)
(你虽然没问这个,但我觉得还是有必要写下。)
bit = (variable >> n) & 1U;
先将 variable 右移 n 位,然后和 1 进行与操作,得到的值赋给变量 bit。如果第 n 位是 1,那么 bit 也会变为 1;如果是 0,bit 也会是 0。
根据另一个变量来置-位
variable ^= (-x ^ variable) & (1UL << n);
如果 x 等于 1,就把 variable 的第 n 位置为 1;如果 x 等于 0,就把 variable 的第 n 位置为 0。
注意,如果 x 等于其它数(非 0 非 1),上面的式子结果就未知了。当然你可以使用逻辑运算符!来把 x 置 0 或 置1(也就是布尔化)。
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
variable ^= (-newbit ^variable) & (1UL << n);
译注:原文中还有一段没有翻译,因为我不知道怎么翻译,这里原文贴在这里(此处的代码我在 Visual Studio 2017 上报错:一元负运算符应用于无符号类型,结果仍为无符号类型)。
To make this independent of 2’s complement negation behaviour (where -1 has all bits set, unlike on a 1’s complement or sign/magnitude >C++ implementation), use unsigned negation.
variable ^= (-(unsigned long)x ^ variable) & (1UL << n);
除了上面的方法,你还可以这么做(推荐):
variable = (variable & ~(1UL << n)) | (x << n);
(variable & ~(1UL << n)) 会对第 n 位清零(clear),(x << n)左移 n 位,也就是赋值第 n 位为 0 或 1。同样的,只有 x 等于 0 或者 1 才会生效,如果是其它的数,结果未知。
另外,如果把这些操作封装在宏里,那么用起来就会显得清楚明白和简洁,可以参考 https://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit/263738#263738。
浙公网安备 33010602011771号