我是bitwise运算符的新手。
我理解逻辑函数如何工作以获得最终结果。例如,当您按位AND
两个数字时,最终结果将是这两个数字的AND
(1 & 0 = 0
; 1 & 1 = 1
; 0 & 0 = 0
) 。与OR
,XOR
和NOT
相同。
我不明白的是他们的申请。我试着到处寻找,其中大多数只是解释按位操作是如何工作的。在所有按位运算符中,我只理解移位运算符的应用(乘法和除法)。我也遇到了掩蔽。我理解屏蔽是使用按位AND
完成的,但究竟是什么目的以及我在何处以及如何使用它?
你能详细说明我如何使用遮蔽吗? OR
和XOR
是否有类似用途?
答案 0 :(得分:16)
按位运算符的低级用例是执行基数2数学运算。有一个众所周知的技巧来测试一个数字是2的幂:
if ((x & (x - 1)) == 0) {
printf("%d is a power of 2\n", x);
}
但是,它也可以提供更高级别的功能:设置操作。您可以将一组位集合视为一组。为了解释,让一个字节中的每个位代表8个不同的项目,比如我们太阳系中的行星(冥王星不再被认为是行星,所以8就足够了!):
#define Mercury (1 << 0)
#define Venus (1 << 1)
#define Earth (1 << 2)
#define Mars (1 << 3)
#define Jupiter (1 << 4)
#define Saturn (1 << 5)
#define Uranus (1 << 6)
#define Neptune (1 << 7)
然后,我们可以形成一组行星(子集),就像使用|
:
unsigned char Giants = (Jupiter|Saturn|Uranus|Neptune);
unsigned char Visited = (Venus|Earth|Mars);
unsigned char BeyondTheBelt = (Jupiter|Saturn|Uranus|Neptune);
unsigned char All = (Mercury|Venus|Earth|Mars|Jupiter|Saturn|Uranus|Neptune);
现在,您可以使用&
来测试两个集合是否有交集:
if (Visited & Giants) {
puts("we might be giants");
}
^
操作通常用于查看两个集合之间的不同(集合的并集减去它们的交集):
if (Giants ^ BeyondTheBelt) {
puts("there are non-giants out there");
}
因此,将|
视为联合,将&
视为交集,将^
视为联合减去交集。
一旦你接受了表示集合的位的想法,那么按位运算自然会帮助操作这些集合。
答案 1 :(得分:3)
按位AND的一个应用是检查是否在一个字节中设置了一个位。这在网络通信中很有用,其中协议报头尝试将尽可能多的信息打包到最小区域中以尽可能减少开销。
例如,IPv4标头利用第6个字节的前3位来判断给定的IP数据包是否可以被分段,如果是,则是否期望跟随给定数据包的更多片段。如果这些字段的大小为整数(1字节),则每个IP数据包将比必要的大21位。这每天都会通过互联网转化为大量不必要的数据。
要检索这3位,可以在位掩码旁边使用按位AND来确定它们是否已设置。
char mymask = 0x80;
if(mymask & (ipheader + 48) == mymask)
//the second bit of the 6th byte of the ip header is set
答案 2 :(得分:3)
小集,如前所述。你可以快速完成大量的操作,交集和联合以及(对称)差异显然是微不足道的,但是例如你也可以有效:
x & -x
x & (x - 1)
1和2及其变体可用于在小图上构建有效的图算法,例如参见“计算机编程艺术4A”中的算法R.
按位运算的其他应用包括但不限于
这些用途更强大,但也更先进,更罕见,更具体。然而,他们表明,按位操作不仅仅是旧的低级别日子遗留下来的可爱玩具。
答案 3 :(得分:1)
如果您有10个“一起工作”的布尔值,您可以大大简化您的代码。
int B1 = 0x01;
int B2 = 0x02;
int B10 = 0x0A;
int someValue = get_a_value_from_somewhere();
if (someValue & (B1 + B10)) {
// B1 and B10 are set
}
与硬件接口。硬件上的地址可能需要位级访问来控制接口。例如缓冲区或状态字节上的溢出位,可以告诉您8种不同的状态。使用位掩码,您可以获得所需的实际信息。
if (register & 0x80) {
// top bit in the byte is set which may have special meaning.
}
这实际上只是示例1的一个特例。
答案 4 :(得分:1)
按位运算符在资源有限的系统中特别有用,因为每个位都可以编码布尔值。使用许多字符标记是浪费的,因为每个字符占用一个字节的空间(当它们每个可以存储8个标记时)。
通常微控制器的IO端口具有C接口,其中每个位控制8个端口中的1个。如果没有按位运算符,这些将很难控制。
关于掩蔽,通常使用&amp; amp; amp;和|:
x & 0x0F //ensures the 4 high bits are 0
x | 0x0F //ensures the 4 low bits are 1
答案 5 :(得分:0)