在编程时经常会用到标题所提到的位运算符。位运算符是对二进制数进行操作的。
一般的,我们将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;