改变一个整数的位
Change a bit of an integer
我们有一个整数
int x = 50;
二进制的就是
00110010
如何以编程方式更改第四(第4)位?
您可以通过将一个数字与除第4位以外的其他位置的值进行or运算来设置数字的第4位。这可以通过
x |= (1u << 3);
同样,可以用除第四个位以外的所有位置都为1的值进行与运算来清除第四个位。例如:
x &= ~(1u << 3);
最后,您可以通过将第四个位与除第四个位以外的其他位置的值进行异或运算来切换第四个位:
x ^= (1u << 3);
要了解为什么会这样,我们需要看两件事:
- 在这种情况下,
<<
操作符的行为是什么? - 这里的AND, OR和异或操作符的行为是什么?
在上面的三个代码片段中,我们使用<<
操作符来生成一个值。<<
运算符是位左移运算符,它取一个值,然后将它的所有位向左移若干步。在你的例子中,我使用
1u << 3
取值1(其二进制表示为1),然后将其所有位移动三个位置,用0填充缺失的值。这将创建二进制值1000
,它在第四个位上设置了一个位。
为什么
x |= (1u << 3);
设置数字的第4位?这与OR运算符的工作方式有关。|=
运算符类似于+=
或*=
,除了位或运算符——它相当于
x = x | (1u << 3);
那么为什么用二进制值1000
对x进行or运算来设置它的第4位呢?这与OR的定义方式有关:
0 | 0 == 0
0 | 1 == 1
1 | 0 == 1
1 | 1 == 1
更重要的是,我们可以更紧凑地将其重写为
x | 0 == x
x | 1 == 1
这是一个非常重要的事实,因为它意味着将任何位与0进行或处理不会改变位的值,而将任何位与1进行或处理总是将该位设置为1。这意味着当我们写
时x |= (1u << 3);
since (1) <<3)是一个除了第四个位以外的所有地方都为零的值,按位或使x的所有位保持不变,除了第四个位,然后将其设置为1。更一般地说,对一个由0和1组成的数字进行or运算,将保留位为0的所有值,并设置位为1的所有值。
现在,让我们看看
x &= ~(1u << 3);
使用位补码运算符~
,它取一个数字并翻转它的所有位。如果我们假设整数是两个字节(为了简单起见),这意味着(1u << 3)
的实际编码是
0000000000001000
当我们取它的补码时,我们得到数字
1111111111110111
现在,让我们看看当两个值按位与在一起时会发生什么。AND运算符有一个有趣的真值表:
0 & 0 == 0
0 & 1 == 0
1 & 0 == 0
1 & 1 == 1
或者更简洁:
x & 0 == 0
x & 1 == x
请注意,这意味着如果我们将两个数字放在一起,结果值将使所有与零的位都被置为零,而所有其他位都被保留。这意味着如果我们使用
~(1u << 3)
我们正在与
1111111111110111
因此,根据我们上面的表,这意味着"保留所有的位,除了第四个位,保持原样,然后将第四个位改为零。"
更一般地说,如果你想要清除一组位,在你想要保持位不变的地方创建一个1,在你想要清除位的地方创建一个0。
最后,让我们看看为什么
x ^= (1u << 3)
翻转数字的第4位。这是因为二进制异或运算符有这样一个真值表:
0 ^ 0 == 0
0 ^ 1 == 1
1 ^ 0 == 1
1 ^ 1 == 0
注意
x ^ 0 == 0
x ^ 1 == ~x
其中~x
为x的对立面;1等于0,0等于1。这意味着如果我们将x与值(1u << 3)
进行异或,我们将与
0000000000001000
所以这意味着"保持除第4位以外的所有位不变,但翻转第4位。"更一般地说,如果你想要翻转一些位,把这个值与一个数字进行异或,在这个数字中,你想要保持这些位的完整性,而在你想要翻转这些位的地方,这个数字是0。
希望这对你有帮助!
您始终可以使用std::bitset
,这使得修改位容易。
或者您可以使用位操作(假设您的意思是计数为1的第4位)。请注意,我使用1U
只是为了保证整个操作发生在无符号数上:
设置:x |= (1U << (4 - 1));
清除:x &= ~(1U << (4 - 1));
To toggle: x ^= (1U << (4 - 1));
设置第4位,OR
与00001000
(二进制)。
用11110111
(二进制)清除第4位AND
。
将XOR
与00001000
(二进制)交换。
例子:
00110010 OR 00001000 = 00111010
00110010 AND 11110111 = 00110010
00110010 XOR 00001000 = 00111010
很简单,因为你有,或者不管你有什么值
int x = 50;
以编程方式设置第4位(从右开始),
int y = x | 0x00000008;
因为,0x
前缀在数字前表示它是十六进制形式。所以,0x0 = 0000
是二进制的,0x8=1000
是二进制的。这就解释了答案。
在C语言中试试这些函数中的一个来改变n位
char bitfield;
// start at 0th position
void chang_n_bit(int n, int value)
{
bitfield = (bitfield | (1 << n)) & (~( (1 << n) ^ (value << n) ));
}
void chang_n_bit(int n, int value)
{
bitfield = (bitfield | (1 << n)) & ((value << n) | ((~0) ^ (1 << n)));
}
void chang_n_bit(int n, int value)
{
if(value)
bitfield |= 1 << n;
else
bitfield &= ~0 ^ (1 << n);
}
char print_n_bit(int n)
{
return (bitfield & (1 << n)) ? 1 : 0;
}
可以使用二进制的AND和OR来切换第4位
要设置x上的第4位,可以使用x |= 1<<3;
, 1<<3
左移0b0001 3位,产生0b1000。
要清除x上的第四个位,您可以使用x &= ~(1<<3);
,这是0b00110010 (x)和(有效地)0b11110111之间的二进制与,屏蔽掉x中不在第四个位置的每个位,从而清除它。
- C++需要帮助从用户那里获得一个整数,并确保它在另外两个整数之间
- 当我们从/tp地址中添加/减去一个整数时会发生什么
- 如何将一个数组值合并为一个整数c++
- 为什么有时我输入一个整数,程序将第一个输入的数字打印成十进制数?
- 给定一个整数数组,需要在Max_Heap上运行操作。得到错误"segmentation fault",有什么想法吗?(C++)
- 我可以将迭代器递增一个整数吗?
- 有没有办法生成一个包含平方的序列,这些平方加起来就是一个整数平方?
- 我正在尝试制作一个程序,在添加 n 天(整数)后告诉一个人什么是一天(例如星期一等)
- 为什么将两个浮点数相加会得到一个整数C++?
- 编写一个读取五个整数并执行一些任务的C++程序
- 如果我们在其中输入一个整数,则字符会给出整数作为输出,但是当分配给它一个整数时,这不会发生。为什么?
- 给枚举一个整数,并在 C++ 中将其相关值作为字符串获取
- 我需要编写一个程序来读取一个文件,该文件将输出所有唯一的整数,如果已经看到整数,它将被关闭
- 按升序输出整数时,将最后一个整数放在新行上
- 编写一个程序,提示用户输入一个整数,然后输出数字的单个数字和数字的总和
- 我在c++中遇到了一个奇怪的错误,其中一个计算2个小整数加法的语句溢出到一个长值中
- 如何在C++中将一个值拆分为一个十进制整数
- 给定一个整数 N>0,区间 [0, 2^N) 中有多少个整数正好有 N-1 个设置位?编写一个返回正确答案的简短函数
- 我必须更改我的数字最后一个数字和第一个数字,但不要使用仅带有整数或循环的函数.例如从 12345 到 52341
- 将整数范围映射到另一个范围