位运算 之(2) 按位异或(xor)^ 操作

按位异或运算

  俗称: xor 运算

 

1 xor 的基本知识

 

我们来看看 xor 运算的机理:

 

1 001 01 100101 1---- à a

xor     1 011 01 000111 0---- à b

-------------------------

      0 010 00 100010 1--- à c

 

看了上面的式子,体会到异或运算的原理了吧,就是: 0 1 异或 0 都不变,异或 1 则取反。很容易理解,如果 b 中的某位为 1 ,那么 a xor b 的作用是在 a 相应的位进行取反操作。用通俗易懂的语言来讲就是 xor 运算通常用于对二进制的特定一位进行取反操作。

我们再看到上面那个计算式子,如果得到的结果 c 再与 b 做异或运算即:

 

0 010 00 100010 1--- à c

xor    1 011 01 000111 0--- à b

----------------------------------

      1 001 01 100101 1--- à d

 

注意到了吧, a == d  是成立的!那么我们可以得到一个结论: (a xor b) xor b = a

同时我们还可以得到一个很诡异的 swap 操作:

a   ^=   b;   b ^= a; a ^= b;

自己拿起笔来模拟一下就很清楚的了。

 

2 xor not (按位否)操作之间的关系

 

事实上很简单, nor 操作是 xor 操作的一个特例。取反实质上就是同 1 做异或操作

~x =   x^0x FFFFFFFF

 

3 、两个比较有趣的式子: (n ^(n+1)) ((n ^(n-1))+1)>>1

 

1 )首先来看 (n ^(n+1)) 这个式子,假设 n = 10011010 n+1 = 10011011 ,则:

 

10011010--- à n

xor    1 0011 011 --- à n+1

------------------------------------

      00000001 --- à ans

 

如果还不能看出什么的话,再来一个例子: n = 11111111 n+1 = 100000000 ,则:

 

11110111--- à n

xor      11111 000--- à n+1

-------------------------

      000001111 --- à ans

 

得到的结果为 n 的倒数出现第一个 0 的位以及后面所有的 1 全部变成 1 ,其它位都为 0 的数。

 

 

2 )再来看看 ((n ^(n-1))+1)>>1 这个式子

假设 n = 10011010 n-1 = 10011001 ,则:

 

10011010--- à n

xor    1 0011 001 --- à n-1

-----------------------------------------

      00000011 --- à ans

ans+1 >> 1   = 000000100 >> 1 = 000000010

 

看出来了吧,也就是取出 n 出现倒数第一个 1 的位及该位后面的 0 组成的数

 

4 、统计 n 1 的奇偶性

 

思路:我们在按位与运算的时候学过了怎么计算一个整数中 1 的个数,但是我们现在用 xor 来解决吧:

=  x  ^  (x >> 1 );
=  x  ^  (x >> 2 );
=  x  ^  (x >> 4 );
=  x  ^  (x >> 8 );
=  x  ^  (x >> 16 );
return  x & 1 ;

 

 

 

说道这里,顺便提一下怎么求解一个数 n 的前导 0 的个数,下面的代码来自 Hacker's Delight

int  nlz(unsigned x)
{
int  n;
if  (x  ==   0 return ( 32 );
   n  =   1 ;
   
if  ((x  >>   16 ==   0 ) {n  =  n  + 16 ; x  =  x  << 16 ;}
   
if  ((x  >>   24 ==   0 ) {n  =  n  +   8 ; x  =  x  <<   8 ;}
   
if  ((x  >>   28 ==   0 ) {n  =  n  +   4 ; x  =  x  <<   4 ;}
   
if  ((x  >>   30 ==   0 ) {n  =  n  +   2 ; x  =  x  <<   2 ;}
   n  =  n  -  (x  >>   31 );
   
return  n;
} // 代码自己慢慢理解吧
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值