您好,欢迎访问三七文档
当前位置:首页 > 中学教育 > 初中教育 > C语言位操作运算详解
位运算程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作位操作的优势位运算是一种底层的运算,往往比我们普通的运算要快上许多许多位运算是最高效而且占用内存最少的算法操作,执行效率非常高位运算操作的是二进制数,会拥有一些二进制的特性,在实际问题可以方便运用位运算只需较低的空间需求位运算使用能使程序变得更加简洁和优美位运算可以表示一些状态集合运算符号下面的a和b都是整数类型,则:含义C语言按位与a&b按位或a|b按位异或a^b按位取反~a左移ab带符号右移ab无符号右移优先级C语言中位运算符之间,按优先级顺序排列为优先级符号1~2、3&4^5|6&=、^=、|=、=、=概念简介以及技巧本文会以C语言的交互环境来做代码演示常见的二进制位的变换操作and运算&判断奇偶数对于除0以外的任意数x,使用x&1==1作为逻辑判断即可if(x&1==1){}判断某个二进制位是否为1比如第7位,0x40转到二进制是01000000,代表第7位是1.if(n&0x40){//TODO:添加你要处理的代码}字节读取(x0)&0x000000ff/*获取第0个字节*/(x8)&0x000000ff/*获取第1个字节*/(x16)&0x000000ff/*获取第2个字节*/(x24)&0x000000ff/*获取第3个字节*/判断一个数是不是22的指数boolisPowerOfTwo(intn){if(n=0)returnfalse;return(n&(n-1))==0;}取余//得到余数intYu(intnum,intn){inti=1n;returnnum&(i-1);}指定二进制位数截取比如说16位二进制数A:1001100110011000,如果来你想获A的哪一位的值,就把数字B:0000000000000000的那一位设置为1.比如说我想获得A的第三位就把B的第三位数字设置为1,则B为0000000000000100,设置完之后再把A、B求与,其结果若为0,说明A的第三位为0,其结果为1,说明A的第三位为1.同理:若要获得A的第五位,就把B设置为0000000000010000,之后再求与。通常在我们的程序中,数字B被称为掩码,其含义是专门用来测试某一位是否为0的数值。统计二进制中1的个数利用x=x&(x-1),会将x用二进制表示时最右边的一个1变为0,因为x-1会将该位变为0.intCount(intx){intsum=0;while(x){sum++;x=x&(x-1);}returnsum;}or操作生成组合编码,进行状态压缩当把二进制当作集合使用时,可以用or操作来增加元素。合并编码在对字节码进行加密时,加密后的两段bit需要重新合并成一个字节,这时就需要使用or操作。求一个数的二进制表达中0的个数intGrial(intx){intcount=0;while(x+1){count++;x|=(x+1);}returncount;}xor操作两个整数交换变量名voidswap(int&a,int&b){a^=b;b^=a;a^=b;}判断两个数是否异号intx=-1,y=2;boolf=((x^y)0);//trueintx=3,y=2;boolf=((x^y)0);//false数据加密将需要加密的内容看做A,密钥看做B,A^B=加密后的内容C。而解密时只需要将C^密钥B=原内容A。如果没有密钥,就不能解密!#includestdio.h#includestdlib.h#includestring.h#defineKEY0x86intmain(){charp_data[16]={HelloWorld!};charEncrypt[16]={0},Decode[16]={0};inti;for(i=0;istrlen(p_data);i++){Encrypt[i]=p_data[i]^KEY;}for(i=0;istrlen(Encrypt);i++){Decode[i]=Encrypt[i]^KEY;}printf(Initialdate:%s\n,p_data);printf(Encryptdate:%s\n,Encrypt);printf(Decodedate:%s\n,Decode);return0;}数字判重利用了二进制数的性质:x^y^y=x。我们可见,当同一个数累计进行两次xor操作,相当于自行抵销了,剩下的就是不重复的数找出没有重复的数intfind(int[]arr){inttmp=arr[0];for(inti=1;iarr.length;i++){tmp=tmp^arr[i];}returntmp;}not操作交换符号intreversal(inta){return~a+1;}取绝对值(效率高)1.n31取得n的符号2.若n为正数,n31等于03.若n为负数,n31等于-14.若n为正数n^0=0,数不变5.若n为负数,有n^-1需要计算n和-1的补码,然后进行异或运算,结果n变符号并且为n的绝对值减1,再减去-1就是绝对值intabs(intn){return(n^(n31))-(n31);}也可以这样使用intabs(intn){inti=n31;returni==0?n:(~n+1);}从低位到高位.将n的第m位置1将1左移m-1位找到第m位,得到000...1...000,n在和这个数做或运算intsetBitToOne(intn,intm){returnn|(1(m-1));}同理从低位到高位,将n的第m位置0,代码如下intsetBitToZero(intn,intm){returnn&~(1(m-1));}shl操作&shr操作求2的N次方1n高低位交换unsignedshorta=34520;a=(a8)|(a8);进行二进制逆序unsignedshorta=34520;a=((a&0xAAAA)1)|((a&0x5555)1);a=((a&0xCCCC)2)|((a&0x3333)2);a=((a&0xF0F0)4)|((a&0x0F0F)4);a=((a&0xFF00)8)|((a&0x00FF)8);获得int型最大最小值intgetMaxInt(){return(131)-1;//2147483647,由于优先级关系,括号不可省略}intgetMinInt(){return131;//-2147483648}m的n次方//自己重写的pow()方法intpow(intm,intn){intsum=1;while(n!=0){if(n&1==1){sum*=m;}m*=m;n=n1;}returnsum;}找出不大于N的最大的2的幂指数intfindN(intn){n|=n1;n|=n2;n|=n4;n|=n8//整型一般是32位,上面我是假设8位。return(n+1)1;}二分查找32位整数的前导0个数intnlz(unsignedx){intn;if(x==0)return(32);n=1;if((x16)==0){n=n+16;x=x16;}if((x24)==0){n=n+8;x=x8;}if((x28)==0){n=n+4;x=x4;}if((x30)==0){n=n+2;x=x2;}n=n-(x31);returnn;}位图的操作将x的第n位置1,可以通过x|=(xn)来实现set_bit(charx,intn);将x的第n位清0,可以通过x&=~(1n)来实现clr_bit(charx,intn);取出x的第n位的值,可以通过(xn)&1来实现get_bit(charx,intn);如下:#defineclr_bit(x,n)((x)&=~(1(n)))#defineset_bit(x,n)((x)|=(1(n)))#defineget_bit(x,n)(((x)(n))&1)
本文标题:C语言位操作运算详解
链接地址:https://www.777doc.com/doc-6826428 .html