位运算、左右移运算
一、位运算
位运算是只适合于整型,并且是对应于二进制进行的一种计算方法,包括位与&、位或|、异或^、取反~。
1.位运算的使用
要进行位运算,首先要将数据转化为二进制数。
(1)位与运算
当两数同时为1时,结果为1,否则为0。
#include<stdio.h>
int main()
{
char a = 20, b = 12;
char c = 0;
c = a & b;
printf("c=%d\n", c);
return 0;
}
运行结果:
(2)位或运算
两数中任意一位为1,运算结果为1,否则为0。
#include<stdio.h>
int main()
{
char a = 20, b = 12;
char c = 0;
c = a | b;
printf("c=%d\n", c);
return 0;
}
运行结果:
(3)异或运算
两数相异值为1,否则为0;当自己和自己异或时,结果为0。
#include<stdio.h>
int main()
{
char a = 20, b = 12;
char c = 0;
c = a ^ b;
printf("c=%d\n", c);
return 0;
}
运算结果:
(4) 取反运算
0变1,1变0。
#include<stdio.h>
int main()
{
char a = 20, b = 12;
char c = 0;
c = ~a;
printf("c=%d\n", c);
return 0;
}
运算结果用十六进制表示:
因为char类型默认有符号位,打印时扩充符号位,结果如下:
(5)左移运算
低位补0,高位移除。
#include<stdio.h>
int main()
{
char a = 12;
a = a<<1;
printf("a=%d\n", a);
a = a << 1;
printf("a=%d\n", a);
a = a << 1;
printf("a=%d\n", a);
a = a << 1;
printf("a=%d\n", a);
a = a << 1;
printf("a=%d\n", a);
a = a << 1;
printf("a=%d\n", a);
return 0;
}
(6)右移运算
有符号时补符号位,无符号位补0。
二、检测一个二进制数据中有多少个1的方法
- [ 第一种] 让二进制数和1进行与运算,如果结果为1,则1的个数加1,否则将次数右移一位在进行与运算,指到次数为0(此种方法只适用于无符号二进制数)。
#include<stdio.h>
int GetBit(unsigned int x)
{
int sum = 0;
while (x != 0)
{
if (x & 0x01)
{
sum += 1;
}
x = x >> 1;
}
return sum;
}
int main()
{
unsigned int x = 0x1ff;
printf("%d\n", GetBit(x));
}
- [ 第二种] 令二进制数x和x-1进行与运算,得到的结果d在和d-1进行与运算,依次类推,指到结果为零,进行与运算的次数就是1的个数。(对有符号数和无符号数同样适用)
#include<stdio.h>
int GetBit(unsigned int x)
{
int sum = 0;
while (x != 0)
{
x = x & (x - 1); //规律:每进行一次与运算,消掉一个1;
sum++;
}
return sum;
}
int main()
{
unsigned int x = 0x1ff;
printf("%d\n", GetBit(x));
}
- [ 第三种] 查表法。
此种方法要用到转义字符的用法,用此方法依次类推:
#include<stdio.h>
int GetBit(unsigned int x)
{
int sum = 0;
for (int i=0;i<8;++i)//转义字符转义时不能超过8进制的超过权重的值
{
sum += "\0\1\1\2\1\2\2\3\1\2\2\3\2\3\3\4"[x & 0x0f]; //对有符号数和无符号数同样适用;
x = x >> 4;
}
return sum;
}
int main()
{
unsigned int x = 0x1ff;
printf("%d\n", GetBit(x));
}
三、检测一个数组中只出现一次的值的方法
一个二进制数异或自己时,值为0。
#include<stdio.h>
int main()
{
int ar[]={2,3,4,6,5,7,5,4,3,2,6};
int tmp=ar[0];
int [n]=sizeof(ar)/sizeof(ar[0]);
for(int i=1;i<n;i++)
{
tmp=tmp^ar[i];//异或运算有交换律
}
printf("%d\n",tmp);
return 0;
}
执行结果: