位运算
x-n
x-n可以写成x+~n+1(相当于-n可以表示为 ~n+1,所以-1直接可用 ~0表示。
pow2plus1函数
#include<stdio.h>
int pow2plus1(int x){
return (1<<x)+1;
}
int main(){
printf("%d\n",pow2plus1(6));
}
//计算公式2^x+1;因为十进制是以2为幂;
setMask函数
将字x中第n位设置为1;其中0<=n<=31;
***思路:通过或逻辑“|”来是的其置为1;
#include<stdio.h>
int setMask(int x,int n){
return (1<<n)|x;
}
int main(){
printf("%d",setMask(7,5));
}
clearMask函数
将字x中第n位设置为0;其中0<=n<=31;
#include<stdio.h>
int clearMask(int x,int n){
return ~(1<<n)&x;
}
int main(){
printf("%d",clearMask(6,2));
}
***思路二(较繁琐)***
#include<stdio.h>
int clearMask(int x,int n){
if(x<1<<n)
return x;
else
return x+~(1<<n)+1;
}
int main(){
printf("%d\n",clearMask(4,2));
}
bitAnd函数
在不使用&符号的情况下完成与运算
#include<stdio.h>
int bitAnd(int x,int y){
return ~(~x|~y);
}
int main(){
printf("%d\n",bitAnd(6,5));
}
getByte函数
从字x中提取第n个字节
思路:先去掉需要保存字节后的字节,再与0xff&从而去掉了之前的字节,保留下来需要的字节//
#include<stdio.h>
int getByte(int x,int n){
return (x>>(n<<3))&0xff;
}
int main(){
printf("%x\n",getByte(0x12345678,1));
}//一个字节8个比特,所以3 2 1 0,第一个字节是0x56//
//思路在于我们如何去除掉0x56的前后//
logicalShift函数
x右移动n位,这里要求是逻辑右移。
注意:正常来说我们输入的是int类型,这就代表着这是一个有符号型,计算机就默认是算术右移(即符号位为0补0,为1则补1)
#include<stdio.h>
int logicShift(int x,int n){
// return (x>>n)&~(0xffffffff<<(32+~n+1));
return (x>>n)&~((1<<31)>>n<<1);
}
int main(){
printf("0x%08x",logicShift(0x87654321,4));
}
思路讲解:思路一:在32位的情况下,我们只要确定把那些位变成0就行,所以我们用了0xffffffff,因为我们要把算术右移的n位变成0所以我们让0xffffffff做移动32-n位,再对其取反就得到了0x0…0f…f,这样再与算术右移取与,就得到了我们想要的逻辑右移//
思路二,当然我们亦可通过详细的位移动来实现,我们将1左移动31位后变成0x80…0的一个值再向右移动n位,此时取反变成0x0…8f…f,因为我们在此前多了一个1,所以在移动时我们在向左移动1位来构成0x0…0f…f//
bitCount函数
返回字节中1的个数
int bitCount(int x){
int i;
for(i=0;x!=0;x>>=1)
if(x&1)i++;// for(i=0;x!=0;x&=(x-1))//
i++;
return i;
}
int main()
{
printf("%x",bitCount(7));
}
bang函数
计算!x,bang(1)=0;bang(0)=1;
int bang(int x)
{// return ~(x|~x+1>>31)&1;
return ~(~x+1>>31)&1;}
int main(){
printf("%x",bang(0));}