位运算符有:&(按位与)、|(按位或)、^(按位异或)、~ (按位取反)。
优先级从高到低,依次为~、&、^、|,

位运算符的一些简单应用:
按位与运算有两种典型用法,一是取一个位串信息的某几位,如以下代码截取x的最低7位:x & 0177。二是让某变量保留某几位,其余位置0,如以下代码让x只保留最低6位:x = x & 077。

按位或运算的典型用法是将一个位串信息的某几位置成1。如将要获得最右4为1,其他位与变量j的其他位相同,可用逻辑或运算017|j

按位异或运算的典型用法是求一个位串信息的某几位信息的反。如欲求整型变量j的最右4位信息的反,用逻辑异或运算017^j,就能求得j最右4位的信息的反,即原来为1的位,结果是0,原来为0的位,结果是1。 交换两个值,不用临时变量,假如a=3,b=4。想将a和b的值互换,可以用以下赋值语句实现:
a=a^b;  b=b^a;     a=a^b;

取反运算常用来生成与系统实现无关的常数。如要将变量x最低6位置成0,其余位不变,可用代码x = x & ~077实现。以上代码与整数x用2个字节还是用4个字节实现无关。
当两个长度不同的数据进行位运算时(例如long型数据与int型数据),将两个运算分量的右端对齐进行位运算。如果短的数为正数,高位用0补满;如果短的数为负数,高位用1补满。如果短的为无符号整数,则高位总是用0补满。

位运算用来对位串信息进行运算,得到位串信息结果。如以下代码能取下整型变量k的位串信息的最右边为1的信息位:((k-1)^k) & k。

对于带符号的数据,如果移位前符号位为0(正数),则左端也是用0补充;如果移位前符号位为1(负数),则左端用0或用1补充,取决于计算机系统。对于负数右移,称用0 补充的系统为“逻辑右移”,用1补充的系统为“算术右移”。以下代码能说明读者上机的系统所采用的右移方法:
     printf("%d\n\n\n", -2>>4);
若输出结果为-1,是采用算术右移;输出结果为一个大整数,则为逻辑右移。

移位运算与位运算结合能实现许多与位串运算有关的复杂计算。设变量的位自右至左顺序编号,自0位至15位,有关指定位的表达式是不超过15的正整数。以下各代码分别有它们右边注释所示的意义:
   (1) 判断int型变量a是奇数还是偶数,尤其是对大数的判断
        a&1 == 0 偶数
        a&1 == 1 奇数
    (2) 取int型变量a的第k位 (k=0,1,2……sizeof(int))
 a>>k&1
    (3) 将int型变量a的第k位清0
 a=a&~(1<<k)
    (4) 将int型变量a的第k位置1
 a=a|(1<<k)
    (5) int型变量循环左移k次
 a=a<<k|a>>16-k   (设sizeof(int)=16)
    (6) int型变量a循环右移k次
 a=a>>k|a<<16-k   (设sizeof(int)=16)
    (7) 实现最低n位为1,其余位为0的位串信息:
 ~(~0 << n)
    (8)截取变量x自p位开始的右边n位的信息:
 (x >> (1+p-n)) & ~(~0 << n) 
    (9)截取old变量第row位,并将该位信息装配到变量new的第15-k位
 new |= ((old >> row) & 1) << (15 – k)
    (10)设s不等于全0,代码寻找最右边为1的位的序号j:
 for(j = 0; ((1 << j) & s) == 0; j++) ;

posted on 2007-04-21 23:42 哈哈 阅读(12570) 评论(9)  编辑 收藏 引用

评论:
# re: 位运算符的一些简单应用 2007-04-22 08:48 | ★田德健★
for(int i = LENGTH; i >= 0; i--)
if(((1 << i) & num) != 0)
std::cout << '1';
else
std::cout << '0';

把num打印成LENGTH长的二进制串:)

  回复  更多评论
  
# re: 位运算符的一些简单应用 2008-09-01 21:59 | 无语
楼主啥意思???
如以下代码截取x的最低7位:x & 0177
瀑布汗  回复  更多评论
  
# re: 位运算符的一些简单应用 2008-09-10 15:54 | haisenior
第一次看到位异或运算可以实现swap(x,y)的,顶!  回复  更多评论
  
# re: 位运算符的一些简单应用 2008-09-26 10:37 | wxhui
@无语
楼主写的没错,是你没看清楚而已,在c或c++语言里,数字可以有3种表示法,十进制,十六进制,和八进制。十进制我们都清楚,十六进制数在数字前面加0x来表示,八进制加0。比如十进制的11,用十六进制表示为0xB,用八进制表示为013
  回复  更多评论
  
# re: 位运算符的一些简单应用[未登录] 2008-10-19 19:58 | lj
)截取old变量第row位,并将该位信息装配到变量new的第15-k位
new |= ((old >> row) & 1) << (15 – k)


假如old 第row为0,new的15-k为1,不就有问题吗?  回复  更多评论
  
# re: 位运算符的一些简单应用[未登录] 2008-10-19 20:10 | lj
(8)截取变量x自p位开始的右边n位的信息:
(x >> (1+p-n)) & ~(~0 << n)

你这个也有问题了  回复  更多评论
  
# re: 位运算符的一些简单应用 2009-02-04 13:29 | mili
真不错, 谢谢, 学习了, 收藏

八进制 0177 我还是习惯写十六进制 7F  回复  更多评论
  
# re: 位运算符的一些简单应用 2009-10-20 17:22 | Lc
关于异或运算实现swap(x,y)
应该是这样:
a = a ^ b
b = a ^ b
a = a ^ b

例:
a = 4, b = 3
(a = 100, b = 11)
a = a ^ b
(a = 100 ^ 11 = 111)
b = a ^ b
(b = 111 ^ 11 = 100)
a = a ^ b
(a = 111 ^ 100 = 11)  回复  更多评论
  
# re: 位运算符的一些简单应用 2010-07-23 18:29 | xiaotang
a&1 == 0改为(a&1) == 0  回复  更多评论
  

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理