清零取反要用与,某位置一可用或
1.与全零,全F的结果及应用
此处仅以32位变量x=0x12345678为例, 设O(zero)=0x00000000, F(one)=0xFFFFFFFF
x&O=0, x&F=x
x|O=x, x|F=F
x^O=x, x^F=~F
所以对于要把变量某些位置0,某些位不变,则选&
要把某些位置1,某些位不变,则选|
要把某些位变为原值的反,某些位不变,则选^
比如将x的最低有效位字节设置成全1,其他字节都保持不变,即变成0x876543FF, 则进行运算x|0x000000FF即可
2.讨论与或非异或结果的完备性
x,y进行操作之后的结果有16种(当x=0,1;y=0,1时),每一类操作只能导出一种结果,比如&操作符0&0=0,0&1=1,1&0=1,1&1=1,结果为[0,1,1,1].这样的结果有16种,两个操作数通过操作符的组合是否可以覆盖16种情况.刚开始因为三种双目操作符的结果都是对称的,写成矩阵[0,1;1,1]的形式.所以我认为不对称的结果是不能通过组合得出的,其实不然,比如[1,0;1,1]是可以通过x|~y得到的.以下是我已经得到的一些结果
[0,0;0,0] = x|~x
[0,0;0,1] = x&y
[0,0;1,0] = x&~y
[0,0;1,1] = (x&y)&(x&~y)
[0,1;0,0] = ~x&y
[0,1;0,1] = ~(x&~y)&(x|y)
[0,1,1,0] = x^y
[0,1;1,1] = x|y
[1,0;0,0] = ~(x|y)
[1,0;0,1] = x&~y
[1,0;1,0] = (x|~y)&~(x&y)
[1,0;1,1] = x|~y
[1,1;0,0] = (~x|y)&~(x&y)
[1,1;0,1] = ~x|y
[1,1;1,0] = ~(x&y)
[1,1;1,1] = ~(x&~x)
这样就证明了这四个符号可以做出任何情况
位运算符的应用 (源操作数s 掩码mask)
二进制补码运算公式:
4.应用举例
(16) x 的 相反数 表示为 (~x+1)
#include <stdio.h>
//设置x的第y位为1
#define setbit(x,y) (x)|=(1<<(y-1))
//得到x的第y位的值
#define BitGet(Number,pos) ((Number)>>(pos-1)&1)
//打印x的值
#define print(x) printf("%d\n",x)
//将整数(4个字节)循环右移动k位
#define Rot(a,k) ((a)<<(k)|(a)>>(32-k))
//判断a是否为2的幂次数
#define POW2(a) ((((a)&(a-1))==0)&&(a!=0))
#define OPPX(x) (~(x)+1)
//返回X,Y 的平均值
int average(int x, int y)
{
return (x&y)+((x^y)>>1);
}
//判断a是否为2的幂次数
bool power2(int x)
{
}
//x与y互换
void swap(int& x , int& y)
{
}
int main()
{
int a=0x000D;
print(a);
int b=BitGet(a,2);
print(b);
setbit(a,2);
print(a);
print(BitGet(a,2));
int c=Rot(a,33);
print(c);
print(BitGet(c,5));
printf("8+5=%d\n",average(8,692));
int i;
for (i=0;i<1000;i++)
{
}
printf("\n");
int x=10,y=90;
swap(x,y);
print(x);
print(y);
print(OPPX(-705));
return 0;
}
5.实例
----------------------+---------------------------+--------------------
去掉最后一位 ¦ (101101->10110) ¦ x >> 1
在最后加一个0 ¦ (101101->1011010) ¦ x < < 1
在最后加一个1 ¦ (101101->1011011) ¦ x < < 1+1
把最后一位变成1 ¦ (101100->101101) ¦ x ¦ 1
把最后一位变成0 ¦ (101101->101100) ¦ x ¦ 1-1
最后一位取反 ¦ (101101->101100) ¦ x ^ 1
把右数第k位变成1 ¦ (101001->101101,k=3) ¦ x ¦ (1 < < (k-1))
把右数第k位变成0 ¦ (101101->101001,k=3) ¦ x & ~ (1 < < (k-1))
右数第k位取反 ¦ (101001->101101,k=3) ¦ x ^ (1 < < (k-1))
取末三位 ¦ (1101101->101) ¦ x & 7
取末k位 ¦ (1101101->1101,k=5) ¦ x & ((1 < < k)-1)
取右数第k位 ¦ (1101101->1,k=4) ¦ x >> (k-1) & 1
把末k位变成1 ¦ (101001->101111,k=4) ¦ x ¦ (1 < < k-1)
末k位取反 ¦ (101001->100110,k=4) ¦ x ^ (1 < < k-1)
把右边连续的1变成0 ¦ (100101111->100100000) ¦ x & (x+1)
把右起第一个0变成1 ¦ (100101111->100111111) ¦ x ¦ (x+1)
把右边连续的0变成1 ¦ (11011000->11011111) ¦ x ¦ (x-1)
取右边连续的1 ¦ (100101111->1111) ¦ (x ^ (x+1)) >> 1
去掉右起第一个1的左边 ¦ (100101000->1000) ¦ x & (x ^ (x-1))
判断奇数 (x&1)==1
判断偶数 (x&1)==0
例如求从x位(高)到y位(低)间共有多少个1
public static int FindChessNum(int x, int y, ushort k)
1026

被折叠的 条评论
为什么被折叠?



