位运算符& 和|的简单说明 .

转载 2012年03月27日 10:10:55

在编程时经常会用到标题所提到的位运算符。位运算符是对二进制数进行操作的。

 

一般的,我们将8位二进制数称为一个字节,如:01011110代表的是10进制的94。

2^8=256,就是说一个字节可以表示的数为256个,即0-255。

为了区分正数和负数,后来又将第一位定为符号位,0为正,1为负。2^7=127,因此一个字节可以表示的数就变为-127——127。

可能有人发现了,这只有255个数。其实少掉的那个数就是10000000,即-0。而00000000则为+0。这就造成了一个数有两种

表达方式,在操作时会造成不便。因此又引入了补码和反码的概念。而目前计算机中的数据都是用补码来保存的。

 

补码:所谓补码,是对原二进制数进行变换而得来的。方法为:

1.若原二进制数为正(包括0),则补码和原二进制数相同。

2.若原二进制数为负,则符号位不变,其他各位取反,然后在末位加1。

 

如:-4,其原码为10000100,按规则,先各位取反->11111011,再末位+1 ->11111100。

值得注意的是-127和-128。-127的原码为11111111先各位取反->10000000,再末位+1->10000001。

事实上,还空出了一个值,10000000,这个值被定为-128的补码。用以替代原先的-0。不过注意,-128没有原码。

补码最大好处是可以将-值作为+值进行计算。这里就不详细介绍了。

 

 

&——按位与。

其作用是将两个二进制数进行比较。若两者相同位上的值皆为1则该位的结果为1,其他情况该位的结果为0。

例: 0000011

     &0001010

—————————

       0000010

 

&的经典应用。从刚才的例子可以看出,a&b时,当b的对应位为0时,无论a该位的值是多少,其结果都为0(绿色部分),

而当b的对应位为1是,其结果就是数a该位的值(红色和蓝色部分)。

因此,&可以对某一二进制数的指定位进行清零。方法是用一个该位为0,其余位为1的数与之做&运算。

 

实例1:在生成随机int数时,会用到Rondom的nextInt()函数。得到的整数正负均有可能。

如果我们希望得到的随机数为正整数,则可以用以下的操作。

nextInt()&0x7fffffff;即可将符号位设为0,使之生成一个正整数。

j2me中用4个字节表示一个整数。4*8=32,其能表现的最大正整数为2^31=2147483648

0x是16进制的标志。一个16进制数相当于4位二进制数。f是10进制的15,二进制则为1111,7的二进制数为0111(0不能省略)。

0x7fffffff就是0111后边跟上7*4=28个1,也就是0后边跟31个1。所以相与后可以将一个32位数的头一位变成0,而其余位保持不变。

 

注意:如此相与后,正数的数值将保持不变。而负数变成正数后其绝对值也将发生变化。原因就是因为计算机的数值是用补码保存的。

因此,千万注意使用的时机。

 

实例2:int keyStates = getKeyStates();

if((keyStates&RIGHT_PRESSED) != 0);

这是GameCanvas判断键盘状态时的经典方法。相信有的人是机械的使用但不知道原理是什么。下面说明一下。

我们在Canvas里判断键盘值的时候用的是等式。因为Canvas里处理的是单一按键。而keyStates可以存储多个按键被按下的情况。

因此无法用等式来比较。假设RIGHT_PRESSED,DOWN_PRESSED,UP_PRESSED,DOWN_PRESSED。

所代表的键值分别为1,2,3,4。那么要区分5是由2和3组成的还是由1和4组成的是不可能的,

事实上,在键值设定上,系统采取了特别的技巧。其二进制键值都是如下格式的:10,100,100000。。。在存储多个按键时,

采取的方式是将按键值相(或的介绍见下边。为何不采用相加的方法请自行思考)。

这样,当对应位的值为1时则表示此位置代表的按键被按下。

比较状态时则用指定按键值与keyStates值相。如果指定位置的值不为1则其结果必为0。表示该按键未被按下。

不过这种处理键值的方式比较浪费位数,所以并未对所有按键进行支持,目前只支持9个。

 

|——按位或。

其作用是将两个二进制数进行比较。若两者相同位上的值有一个为1该位的结果为1,其他情况该位的结果为0。

|可以将某一二进制数的指定位设为1,方法是用一个该位为1,其余位为0数与之做或运算。

 

实例1:nextInt()&0x80000000,其效果是将符号位设为1,使之生成一个负整数。其原理与&近似。而且同样要注意值的改变。

实例2:Graphics.TOP|Graphics.LEFT,原理和上面说过的键值处理类似。

 

特别奉送:位运算符^(异或运算符)。原理不讲了。

使用^可以在没有第三变量的情况下交换两变量的数值。

如:交换a和b的数值。

只需如下步骤:

a=a^b;

b=a^b;

a=a^b;

转载自:http://blog.csdn.net/colaice2009/article/details/5897916

相关文章推荐

简单理解和应用程序中的位运算符

位运算符在实际项目中使用的比较少,但是由于效率高,并且有助于理解程序底层,还有有理解的必要的,我之前一直都位运算符比较疑惑,做了些算法题之后渐渐理解了。 按位与:”&” 例子: 2 (0010)...

C语言位运算符异或^的简单介绍

异或:位运算符,"异或"顾名思义就是两数相"异",则为真(1)。简单的描述其作用就是0^1=1,0^0=0,1^1=0。参加运算的两个二进制位为同号,则结果为0,异号则为1. ___________...
  • NICOC_
  • NICOC_
  • 2017年04月14日 09:08
  • 263

c++运算符重载简单案例,说明一下什么是运算符重载

引入运算符重载的原因例如: int a=1,b=2; float c=1.1,d=2.4; int e=a+b; float f=c+d; float g=f+e; 为什么同一个运算符“...

C/C++ 初学简单笔记 —4.1— 多态性 运算符重载

1. 运算符重载 除了 ?: .  *  ::  sizeof  这些运算符不能重载外,其他的运算符都能重载 运算符的重载一般用成员函数或是友元函数来重载 一般形式为:函数类型  operato...

C++运算符重载简单学习-----菜鸟潇寒

最近在学习C++的时候突然发现有一个很好玩的东西,就是运算符的重载。 运算符重载是对已有的运算符赋予更多的含义,使同一个运算符会有意想不到好处与方便。 下面我们就简单地介绍运算符的重载。 1.首先在...

【C语言简单说】五:常用运算符

其实。。。这一节我我猜大家几分钟就会了()…(⊙_⊙;)… ○圭~○列~~怎麼酱?因为我相信大家的智商,我就随便给大家提一下就好了。我们看以下的代码:#include #include int mai...

【C语言简单说】十三:逻辑运算符||

(+﹏+)~ 更完睡觉=。=这一节我们来说说逻辑或||,其实很简单的,既然你们理解了第一个逻辑与,那么逻辑或就没什么难度了。我们说过逻辑与就像我们的并列关系,例如我们吃了苹果和李子。我们现在的逻辑...

【C语言简单说】六:取模运算符以及变量的扩展

┴┴ (╰(`□′)╯( ┴┴ … 这一节我们就来说另外的运算符——取模运算符(说白了跟取余数差不多…<—_-)!!!)先看看好难懂的定义:取模运算和取余运算两个概念有重叠的部分但又不完全一致。…...

javascript:从 复选框来选中俩个数值,然后从单选框按钮来选择加减乘除运算符,实现简单的计算器.

+ - * / function init() { for(i=0; i

复数类-简单的运算符重载

运算符重载可以使一些现有的运算符实现一些特定的功能。 运算符重载函数的基本格式: 函数类型 operator@(参数列表) //@代表要重载的运算符常见的单目运算符:++、...
  • CCSUXWZ
  • CCSUXWZ
  • 2017年01月28日 18:39
  • 82
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:位运算符& 和|的简单说明 .
举报原因:
原因补充:

(最多只允许输入30个字)