❤️今天我们来学习位或
注意:本文中的位是从右往左来说的,也就是从低位开始数的!!!
✨要想解决这个问题,我们先要搞清楚,2的幂有什么特征?
2的幂 | 十进制表达 | 二进制表达 |
---|---|---|
2^0 | 1 | 0001 |
2^1 | 2 | 0010 |
2^2 | 4 | 0100 |
2^3 | 8 | 1000 |
… | … | … |
✨我们简单地列举出几个2的幂的二进制表达,可以发现,只有一位是1(且是首位),其余位全部是0。利用昨天学过的位与(&)知识,全1才1,有0则0,因此,将(2^n) & (2^n-1),结果必定是0,从而得到判断一个数是否是2的幂的方法之一:
if ( (n)&(n-1)==0 ) cout<<"n是2的幂";
✨C语言中的位或运算符|
是一种按位逻辑
运算符,用于对两个操作数
的每个位
执行逻辑或操作。位或操作的结果是两个操作数的每个对应位进行逻辑或
运算后的值。
位或运算符的使用方法如下:
result = operand1 | operand2;
operand1
和operand2
是要进行位或运算的两个操作数,result
是运算结果。位或运算的规则如下:
(全0才0)
如果两个操作数的对应位都为0,则结果位为0。(有1则1)
如果两个操作数的对应位有一个为1,则结果位为1。(是不是和逻辑或很像呢❓)
示例如下:
#include
int main() {
unsigned int a = 5; // 二进制表示为 0101
unsigned int b = 9; // 二进制表示为 1001
unsigned int result = a | b; // 二进制表示为 1101,十进制表示为 13
printf("result: %u\n", result);
return 0;
}
a
和b
,它们的二进制表示分别为0101
和1001
。通过对这两个变量进行位或运算,我们得到了结果1101
,它的十进制表示为13。✨可以使用位或运算将某个变量的特定位设置为1,而不影响其他位的值。例如,可以使用位或运算设置标志位、控制位或权限位。
示例如下::
#include
int main() {
unsigned int flags = 0; // 所有位都为0
unsigned int mask = 1; // 二进制表示为 0001
flags = flags | mask; // 将最低位设置为1
printf("flags: %u\n", flags);
return 0;
}
flags
,它的所有位都为0。然后,我们定义了一个二进制表示为0001
的掩码mask
。通过对flags
和mask
进行位或运算,我们将flags
的最低位设置为1。最终,flags
的值变为1。❤️怎么将任意二进制的特定位置为1呢?置为0又该怎么做?
解:
✨我们首先来看第一个问题,将任意二进制的特定位置为1。
我这里有两种方法:
方法一:利用位或的思想
要将一个二进制数的第n位(从右往左,即从低位开始数)置为1,则只需要将该二进制数与2^(n-1)位或即可。比如对1001来说,要将第三位置为0,只需要将其与100(即4=2 ^(3-1))位或即可。
方法二:加法
先将该位置为0,再加上2^(n-1);
✨对于第二个问题,将任意二进制的特定位置为0,解法与第一个问题类似。
方法一:利用位与的思想
将该数和111…101…111位与(这个二进制数只有特定位上是0,其余都是1)。比如要将1011第2位置为0,只需将其和1101位与即可。
方法二:减法
先将该位置为1,再减去2^(n-1);
❤️怎么将低位连续的0置为1呢?
解:对于11110000来说,要想将低位的4给零都置为1,只需要将其和11101111位或
即可。也就是n|(n-1)
.(这是一种特殊情况)
❤️怎么将低位的第一个零置为1呢?
解:对于11110111来说,要想将低位的第一个0置为1,只需要将其和11111000位或
即可。也即n|(n+1)
.(普遍情况)
✨可以使用位或运算将不同的权限组合在一起。例如,可以使用不同的位代表不同的权限,然后通过位或运算将多个权限合并在一起。
#include
#define READ_PERMISSION 1 // 二进制表示为 0001
#define WRITE_PERMISSION 2 // 二进制表示为 0010
#define EXECUTE_PERMISSION 4 // 二进制表示为 0100
int main() {
unsigned int permissions = 0;
permissions = permissions | READ_PERMISSION; // 设置读权限
permissions = permissions | WRITE_PERMISSION; // 设置写权限
printf("permissions: %u\n", permissions);
return 0;
}
permissions
,它的所有位都为0。然后,我们定义了三个不同的权限标志,分别代表读权限、写权限和执行权限。通过对permissions和相应的权限标志进行位或运算,我们将读权限和写权限合并在一起。最终,permissions的值变为3。✨可以使用位或运算来创建一个掩码,用于提取或设置特定的位。掩码是一个二进制数,其中每个位对应于要提取或设置的位。通过将掩码与另一个数进行位与或位或运算,可以提取或设置特定的位。(一般是位与)
#include
#define BIT_MASK 0x0F // 二进制表示为 00001111
int main() {
unsigned int value = 0x3A; // 二进制表示为 00111010
unsigned int maskedValue = value & BIT_MASK;
printf("maskedValue: %u\n", maskedValue);
return 0;
}
✨可以使用位或运算来创建一个包含多个位标志的变量。每个位标志代表一个特定的状态或属性。通过位或运算将多个位标志合并在一起,可以在一个变量中同时表示多个状态或属性。(和权限控制有点类似)
#include
#define FLAG_A 1 // 二进制表示为 0001
#define FLAG_B 2 // 二进制表示为 0010
#define FLAG_C 4 // 二进制表示为 0100
int main() {
unsigned int flags = 0;
flags = flags | FLAG_A; // 设置标志A
flags = flags | FLAG_B; // 设置标志B
printf("flags: %u\n", flags);
return 0;
}
✨有时,使用位或运算可以优化代码的执行效率。例如,可以使用位或运算来替代一些复杂的逻辑运算,从而减少计算量和执行时间。
好了,今天的讲解就到这里了,相信你也是收获满满吧!
附一张漂亮的流星雨照片:(许愿.gif)