您的位置:首页 > 其它

位操作

2015-12-06 22:43 183 查看
1、位操作求两个数的平均值

若用(x+y)/2求两个数的平均值,当两个数比较大时,用这种方法可能会存在数据溢出的情况,采用位运算方法可避免这一问题。

(x&y)+((x^y)>>1) 即是用位运算求解两数的平均值

2、用位运算计算数的绝对值

int MyAbs(int x)
{
int y;
y=x>>31;
return (x^y)-y; //此处也可写成(x+y)^y
}


对于一个负数,将其右移31位后会变成0xffffffff,而对于一个正数而言,右移31位是0x00000000。在计算机中,数字都是以补码的形式存放的。

3、如何求解整型数的二进制表示中1的个数

int Func(int x)
{
int countx=0;
while(x)
{
countx++;
x=x&(x-1);//去掉整数x二进制中的最后一个1
}
return countx;
}

int Func2(unsigned int x)
{
int count=0;
while(x)
{
count+=x&0x1u;
x>>=1;        //此法在1比较稀疏的时候效率比较低
}
return count;
}


4、不能用sizeof()函数时如何判断操作系统是16位还是32位?

#include<stdio.h>
int main()
{
int i=65536;
printf("%d\n",i);
return 0;
}
//16位机器下,无法输出那么大的数,会输出0(出现越界现象),32位机器可正常显示

#include<stdio.h>
int main()
{
unsigned int a=~0;
if(a>65536)
printf("32位\n");
else
printf("16位\n");
return 0;
}
//对0取反,不同位数下结果不同


5、嵌入式编程中,什么大端/小端?

采用小端模式的CPU对操作数的存放方式是从低字节到高字节,而采用大端模式的CPU对操作数的存放方式是从高字节到低字节。

如果能通过代码知道CPU对内存采用小端还是大端模式读写,一定会令面试官刮目相看。

int checkCPU()
{
unsigned short usData=0x1122;
unsigned char* pucData=(unsigned char*)&usData;
return(*pucData==0x22);//返回ture代表是小端模式
}


6、考虑n位二进制数,有多少个数中不存在两个相邻的1

假设所求结果为a(n),则当第n位为0时,个数为a(n-1),第n位为1时,个数为a(n-2),则所求结果a(n)=a(n-1)+a(n-2),满足斐波那契数列,可由递归方法求出:

long Fibo(int i)
{
if((i==1)||(i==2))
return 1;
else
return(Fibo(i-1)+Fibo(i-2));
}


7、一些关于位运算的知识

(1)-n=~(n-1)=~n+1;

(2)n&(-n) 或 n&~(n-1);获取整数n的二进制中的最后一个1

(3)n&(n-1);去掉整数n的二进制中的最后一个n
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: