关于一些位运算的小记

位运算符

对于位运算完全不熟悉,因此开个小记来陆续记录一些遇到的常用位运算 ```&```:按位与,对应的二进制位均为1时返回1,否则返回0; ```|```:按位或,对应的二进制位有一个为1时返回1,否则返回0; ```^```:按位异或,对应的二进制位不同时返回1,否则返回0; ```~```:按位非,对每一位取反; ```<<```:左移; ```>>```:右移; ##位运算的一些技巧 ###```i<>j``` 前者表示i的二进制表示左移j位,等效于i/(2^j);后者表示i的二进制表示右移j位,等效于i*(2^j); ###i&1 求i的最后一位,可判断奇数偶数; ###i^j 比较i与j的每一位,不同时返回1,否则返回0;因此i==j时,i^j=0; ###i&(-i) 返回 i 的二进制数表示为1的最低位的权值,如1001则返回1,1100则返回4,1110则返回2;该运算常用于求和或更新树状数组 ###i&(i-1) 使i二进制表示下最右边的1变为0; 因此: ①可以用i&(i-1)的结果是否为0来判断i是否是2的幂; ②如果要比较m,n的二进制表示有多少位不同,可以 ```C++ int n,m,t,cnt=0; cin >> n>>m; t = n ^ m; while (t) { cnt++; t &= (t - 1); } cout << cnt; ``` n^m的结果将n与m的不同位变为1,相同位变为0,因此只需统计t有多少个1; 用t&(t-1)来依次将t最右边的1改为0,直到t为0;操作的次数即为1的个数。 由此统计m,n不同位的个数 ###i+((i+1)&(-(i+1))) i+1将i最低位的0变为1,后面的1变为0,再用(i+1)&-(i+1)取得其最低位1的权值,加到i上,得到的效果就是将i最低位的0变成1 ###异或运算的一些性质 异或运算的逆运算也是异或运算,即:a^b=c,则有a=b^c; 异或运算具有结合律,因此a^b^b=a
posted @ 2018-03-30 02:15  __orange  阅读(198)  评论(0编辑  收藏  举报