位运算的基础知识和常见应用

//位运算的基础知识及其应用

//基础知识:
//1.位运算的几种常见形式:&,|,>>,<<,^,~(所有位运算都是将数转成二进制进行按位操作)
//2.对几种形式进行一个解释:
//&:表示按位与,其中有0出0,无0(即两个数都为1)出1
//|:表示按位或,其中有1出1,无1(即两个数都为0)出0
//<<:表示左移,每一位都向左移动,(如:11<<x,则表示11转成二进制后的每一位向左移动x位),其中最右
//边的那x位自动补0,并不会进行循环移位
//>>:表示右移:与左移的思路基本类似,左边也是自动补0(对于无符号数),有符号数补的是符号位
//^:表示异或:两个相同数出1,反之出0
//~:取反,即~1=0,~0=1
//3.位运算的优先级低,一般使用都要加括号,才能保证优先进行运算执行

//4.补充%在位运算中优化:求100%8==100-math.floor(100/8)*8==100-((100>>3)<<3),这种方法只有在除数为2的幂次时才能使用.

//应用:

//1.判断奇偶
if (n&1) return /*n为奇数*/;
else return /*n为偶数*/;
//这种位运算方法相较于n%2的方法效率更高

//2.交换数据
void swap(int &x,int &y) {
x^=y;
y^=x;
x^=y;
}
//不用tmp就可实现交换数据

//3.变换符号
//无论是正变负还是负变正,只要将原数取反加1,如11变成-11,则可写出~(11)+1;

//4.高低位的互换
//对于一个16位的二进制数,将它的前八位(高位)和后八位(低位)进行互换,得到一个新的数
//如对一个数:34520 它的二进制数为10000110 11011000,将它向右移8位,则得到了00000000 10000110
//将它左移八位则得到了11011000 00000000,所以要得到11011000 10000110只需要将左移八位和右移
//八位的两个数相或即可,所以:16位二进制数x的高低位互换==(x<<8)|(x>>8)

//5.判断一个数是不是2的整数次方
//一个是2的整数次方的数,它的二进制标识符中有且只有一个1,其他位均为0
//判断方法:把这个数减去1以后在和它本身做与运算,判断是不是为0即可,为0则为2的整次方的数
//分析:因为减去掉一个1肯定有地方损失掉一个1,如果只有一个1,则减完后变为全0,与任何数相与一定
//还是为0

//6.找筷子问题:如一堆筷子中两两成对并且有且仅有一只筷子无法配对,给定所有筷子的长度,输出最终
//剩下来的那根不能配对的筷子的长度.
//分析:此题恰好可以用到异或(^)运算的性质,因为两两相同的数异或就为0,所以所有的成对筷子异或完
//的结果就为0,又因为0与x异或的结果为x,所以将所有的数异或起来的结果就是单独筷子的长度.

//7.memset函数 

memset函数中只能将所有数置为 0或-1,不能是其它数,因为0的二进制为00000000,全为0,-1的二进制为11111111,

而memset内部是以char(字符)类进行转换.

(因为-1+1==0,111111111+1=00000000,所以-1=11111111)

 

posted @ 2021-07-20 18:58  jue1e0  阅读(202)  评论(0)    收藏  举报