[ACM][ASM][0x0001]按位与、按位或、按位异或、按位非、左移、右移

2019-04-14 17:58发布

位操作是程序设计中对位模式或二进制数的一元和二元操作. 在许多古老的微处理器上, 位运算比加减运算略快, 通常位运算比乘除法运算要快很多. 在现代架构中, 情况并非如此:位运算的运算速度通常与加法运算相同(仍然快于乘法运算).
1.按位与"&" eg1
将int型变量n的低8位全置成0,其余位不变,则可执行:
n = n & 0xffffff00;
n &= 0xffffff00;
如果n是short型,只需执行:
n &= 0xff00;


eg2
判断一个int型变量n的第7位(从右往左)是否是1,只需看表达式"n & 0x80"的值是否等于0x80即可
0x80 二进制 0000 0000 0000 0000 0000 0000 0100 0000


2.按位或"|"
按位或运算通常用来将变量某些位置为1或保留某些位不变。
eg1
将int型变量n低8位全置成1,其余位不变,可以执行:
n |= 0xff;


3.按位异或"^"
仅当两个二进位不同时,结果对应的二进位才是1,否则为0。
运算特点:如果a^b=c,那么有c^b==a及c^a==b,可用来快速加密或解密。
a ^ b = c
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0


4.按位非"~"
将二进制位0变为1,1变为0 /******************** 21二进制 : 0000 0000 0000 0000 0000 0000 0001 0101 按位非 : 1111 1111 1111 1111 1111 1111 1110 1010 ********************/ #include int main() { printf("%d, %u, %x", ~21, ~21, ~21); return 0; } /**********output************ -22, 4294967274, ffffffea ****************************/

5.左移"<<"
左操作数:二进制数;右操作数:左移位数;低位补0;移出舍弃。
eg1
9有32位,二进制表示为:
0000 0000 0000 0000 0000 0000 0000 1001
表达式"9 << 4"将上面二进制数左移4位,得到:
0000 0000 0000 0000 0000 0000 1001 0000
即十进制的144
实际上,左移n位就等于乘以2^n。左移操作比乘法快的多。
#include int main() { int n1 = 15; short n2 = 15; unsigned n3 = 15; unsigned char c = 15; n1 <<= 15; n2 <<= 15; n3 <<= 15; c <<= 6; printf("n1=%x, n2=%d, n3=%d, c=%x, c<<4=%d",n1,n2,n3,c,c<<4); return 0; } /**********output************* n1=78000, n2=-32768, n3=491520, c=c0, c<<4=3072 *****************************/


6.右移">>"
左操作数:二进制数;右操作数:右移位数;高位补0;移出舍弃。
有符号数,如long、int、short、char,右移时,符号位即最高位将一起移动,如果原符号位为1,右移时最高位补1;如果原符号位为0,右移时最高位补0。
无符号数,如unsigned long、unsigned int、unsigned short、unsigned char,右移时最高位补0。
#include int main() { int n1 = 15; short n2 = -15; unsigned n3 = 0xffe0; unsigned char c = 15; n1 = n1 >> 2; n2 >>= 3; n3 >>= 4; c >>= 3; printf("n1=%x, n2=%d, n3=%x, c=%x",n1,n2,n3,c); return 0; } /**********output************* n1=3, n2=-2, n3=ffe, c=1 *****************************/