建议先参考有关按位运算符的有趣事实。
1.如何在数字“ num”中设置一位:
如果我们想在数字“ num”中的第n个位置设置一位,则可以使用“或”运算符(|)来完成。
- 首先我们通过(1 << n)左移’1’到n位
- 然后,使用’OR’运算符将位设置在该位置。使用’OR’运算运算符是因为即使先前在数字’num’的二进制表示中未设置该位,也会设置该位。
#include
using namespace std;
// num is the number and pos is the position
// at which we want to set the bit.
void set(int & num,int pos)
{
// First step is shift '1', second
// step is bitwise OR
num |= (1 << pos);
}
int main()
{
int num = 4, pos = 1;
set(num, pos);
cout << (int)(num) << endl;
return 0;
}
输出:
6
我们通过“按引用调用”传递了参数,以永久更改号码。
2.如何取消设置/清除数字“ num”中第n个位置的位:
假设我们想在数字’num’的第n个位置取消设置位,那么我们必须在’AND’(&)运算符的帮助下进行设置。
- 首先,我们通过(1 << n)左移’1’到n位置,而不是使用按位NOT运算符’〜’来取消设置此移位的’1’。
- 现在,清除此左移的“ 1”即使其变为“ 0”后,我们将对“ AND”(&)与数字“ num”进行设置,该数字将在第n个位置取消设置。
#include
using namespace std;
// First step is to get a number that has all 1's except the given position.
void unset(int &num,int pos)
{
//Second step is to bitwise and this number with given number
num &= (~(1 << pos));
}
int main()
{
int num = 7;
int pos = 1;
unset(num, pos);
cout << num << endl;
return 0;
}
输出:
5
3.在第n个位置切换:
切换意味着如果先前将其设为“off”(0),则将其设为“on”(1),如果先前将其设为“on”(1),则将其变为“off”(0)。我们将在此处使用“XOR”运算符是这个“ ^”。 “ XOR”运算符背后的原因是由于其属性。
- ‘XOR’运算符的属性。
- 1 ^ 1 = 0
- 0 ^ 0 = 0
- 1 ^ 0 = 1
- 0 ^ 1 = 1
- 如果两个位不同,则“ XOR”运算符将返回一个设置位(1),否则将返回一个未设置的位(0)。
#include
using namespace std;
// First step is to shift 1,Second step is to XOR with given number
void toggle(int &num,int pos)
{
num ^= (1 << pos);
}
int main()
{
int num = 4;
int pos = 1;
toggle(num, pos);
cout << num << endl;
return 0;
}
输出:
6
4.检查第n个位置的位是否已设置或未设置:
使用’AND’运算符很容易做到。
- 左移’1’到给定位置,然后左移’AND’(’&’)。
#include
using namespace std;
bool at_position(int num,int pos)
{
bool bit = num & (1<
输出:
1
观察到我们首先左移了“ 1”,然后使用“ AND”运算符在该位置获取了位。因此,如果“ num”中位置“ pos”的位置为“ 1”,则在“ AND”之后,变量“ bit”将存储“ 1”,否则如果数字“ num”中位置“ pos”的位置为“ 0”比“与”之后我们的变量位将存储“ 0”。
一些更快速的技巧:
- 反转数字/ 1的补码的每一位:
如果我们想反转数字的每一位,即将位“ 0”更改为“ 1”,将位“ 1”更改为“ 0”。我们可以借助“〜”运算符。例如:如果number为num = 00101100(二进制表示),则’〜num’将为’11010011’。
这也是“ 1的数字补码”。
#include
using namespace std;
int main()
{
int num = 4;
// Inverting every bit of number num
cout << (~num);
return 0;
}
Output:
-5
- 数字的二进制补码:数字的2的补码为1的补码+ 1。
因此,我们可以通过找到1s补码并将1加到结果即(〜num + 1)来正式获得2的补码,否则我们可以使用’-‘运算符。
#include
using namespace std;
int main()
{
int num = 4;
int twos_complement = -num;
cout << "This is two's complement " << twos_complement << endl;
cout << "This is also two's complement " << (~num+1) << endl;
return 0;
}
输出:
This is two's complement -4
This is also two's complement -4
- 剥离最低设置位:
在许多情况下,我们希望剥离最低的设置位,例如在Binary Indexed树数据结构中,将一个设置位的数量计数。
我们做这样的事情:
X = X & (X-1)
但是它怎么工作呢?
让我们来看一个例子,让X = 1100。
(X-1)将所有位取反,直到遇到最低位’1’,并且也将最低位’1’取反。
X-1变为1011。将X与X-1“与”后,我们将剥离掉最低的设置位。
#include
using namespace std;
void strip_last_set_bit(int &num)
{
num = num & (num-1);
}
int main()
{
int num = 7;
strip_last_set_bit(num);
cout << num << endl;
return 0;
}
输出:
6
- 获取数字的最低设置位:
这是通过使用表达式’X&(-X)’完成的,让我们看一个例子:让X =00101100。因此〜X(1的补码)为’11010011’,2的补码为(〜X + 1或-X),即“ 11010100”。因此,如果我们将原始数字“ X”与两个补码“ -X”进行“与”运算,则会得到最低的设置位。
00101100
& 11010100
-----------
00000100
#include
using namespace std;
int lowest_set_bit(int num)
{
int ret = num & (-num);
return ret;
}
int main()
{
int num = 10;
int ans = lowest_set_bit(num);
cout << ans << endl;
return 0;
}
输出:
2
竞争编程的位技巧
有关Bit Hacks的更多文章,请参阅BitWise运营商文章。
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。