如果你是第一次了解位运算,或者对位运算还不熟,请移步位运算
操作对象:整数的补码
位运算,位即是二进制位,而以二进制位方式存储的数据就是整数,而非浮点数 且位运算的对象是补码. 综合来看位运算的操作对象就是整数的补码
下面只提供关键代码及适当分析
简单,但是缺陷明显,负数不管用(负数取余有负数,而二进制只有0和1)
int len=0;
while (n)
{
a[len++] = n % 2;
n /= 2;
}
printf("这个整数的二进制位中1有%d个",len);
for (int i = 0; i < 32; i++)
{
if ((n >> i) & 1 == 1)
{
count++;//count计数
}
}
printf("这个整数的二进制位中1有%d个",count);
while (n)
{
int count = 0;
n=n&(n-1)
count++;
}
printf("这个整数的二进制位中1有%d个",count);
if(n&(n-1)==0)
printf("该数是2的整数次方");
int n = a ^ b;
while (n)
{
int count = 0;
n=n&(n-1)
count++;
}
printf("整数a改变%d处可以得到b整数",count);
本题我有细讲过,速戳 不使用加减法求整数a和整数b的和
while (num2)
{
int temp = num1 | num2;
num2 = (num1 & num2) << 1;
num1 = temp;
}
printf("两个数的和是:%d", num1);
本题我有细讲过,速戳交换ab两数的三种方法
printf("交换前:a=%d\tb=%d\n", a, b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("交换后:a=%d\tb=%d\n", a, b);
问题描述:数组{1,2, 2, 3 , 3 ,4, 4} ----------> return 1;
酷似问题5:
int ans = 0;
for (int i = 0; i < n - 1; i++)
{
ans = ans ^ a[i];
}
printf("单身狗是;%d\n", ret);
问题描述:如果1,2,3…n中丢失了一个数据,让你用位运算的知识找到他
题解思路:
这里好像都是单身狗,那就给他们^异或1,2,3…n,我愿称之为分配对象,没有领到对象的就是那个丢失的数据. 也就是a[0]^ a[1]^ a[2]^ a[3]…a[n]^ 1^2 ^3 ^ 4… ^ n
问题描述:数组{1,2, 3 , 3 ,4, 4} ----------> 找出 1和2;
设两个单身狗分别为x和y,假设第一次异或的结果为ans
先回顾对异或的理解:标记二进制位中不同处位为1
int main()
{
int a[6] = { 1,2,3,3,4,4};
int ans = 0;
//进行第一次异或找到ans
for (int i = 0; i < 6; i++)
{
ans = ans ^ a[i];//两个单身狗异或第一次得到ans
}
//通过ans找到其二进制中第一个二进制位为1的位置,记为pos
int pos = 0;
for (int i = 1; i <= 32; i++)//遍历32个比特位
{
if ((ans >> i) & 1 == 1)
{
pos = i;
break;//找到第一个二进制位为1的位置后跳出
}
}
int x = 0;
for (int i = 0; i < 6; i++)//遍历6个数组元素
{
if((a[i]>>pos)&1==1)//将数组中二进制位pos位置为1的归到这里参与异或
{
x=x^a[i];//异或第二次得到第一个单身狗
}
}
int y = 0;
y=x^ans;//小技巧
printf("单身狗分别是:%d和%d",x,y);
return 0;
}
本题注释中的小技巧:由ans(3)和x(2)求y(1)的原理 1 ^ 2=3 3 ^ 2=3 ^ 1 ^ 1 ^ 2=3 ^ 1 ^ 3 =1