声明:本文部分参考Thinking in Java、http://blog.sina.com.cn/s/blog_60e96a410100mjd2.html
在介绍按位操作符前,本文先导入关于计算机原码,反码,补码的相关概念。
原码(true form)是一种计算机中对数字的二进制定点表示方法。原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1(0有两种表示:+0和-0),其余位表示数值的大小。例如,我们用8位二进制表示一个数,+11的原码为00001011,-11的原码就是10001011
补码(two's complement) 在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。
正整数的补码等于原码,也等于反码。负整数的补码=模-负数的绝对值,如
-1补码:由1 0000 0000-1=1111 1111
-5补码:由1 0000 0000-5=1111 1011
也有这样的算法:负数补码=反码+1(负数反码就对负数原码除符号位取反加1)如:
-1原码:1000 0001 反码:1111 1110 补码:1111 1111
-5原码:1000 0101 反码:1111 1010 补码:1111 1011
计算机的数值一律用补码来存储,所以位操作符所操作的数值在计算机对应的是以补码形式呈现。
好了,现在让我们进入本文主题。
一 按位操作符
在java中,所以数值类型都有正负号,最高位就是符号位,整数位0,负数为1。所以不要去寻找无符号的数值类型。
按位操作符用来操作整数基本数据类型中的单个“比特(bit)”,即二进制位。按位操作符会对两个参数中对应的位执行布尔代数运算,并最终生成一个结果。
Java中有四个按位操作符,分别是“与”操作符(&),“或”操作符(|),“异或”操作符(^),“非”操作符(~)。
1&1=1 ,1&0=0,0&1=0,0&0=0(二进制对应的位都为1的值运算才为1)
1|1=1 ,1|0=1,0|1=1,0|0=0(二进制对应的位只有有一个为1的值运算就为1)
1^1=0 ,1^0=1,0^1=1,0^0=0(二进制对应的位相同为0,不同为1)
~0=1,~1=0
"~" 是一元操作符
按位操作符在程序设计中具有以下几种用法
按位与运算有两种典型用法,一是取一个位串信息的某几位,如以下代码截取x的最低7位:x & 0177。二是让某变量保留某几位,其余位置0,如以下代码让x只保留最低6位:x = x & 077。以上用法都先要设计好一个常数,该常数只有需要的位是1,不需要的位是0。用它与指定的位串信息按位与。
按位或运算的典型用法是将一个位串信息的某几位置成1。如将要获得最右4为1,其他位与变量j的其他位相同,可用逻辑或运算017|j。若要把这结果赋给变量j,可写成:
j = 017|j
异或运算符可以交换连个变量,如
想将a和b的值互换,可以用以下赋值语句实现:
a=a∧b;
b=b∧a;
a=a∧b;
a=011(2)
(∧)b=100(2)
a=111(2)(a∧b的结果,a已变成7)
(∧)b=100(2)
b=011(2)(b∧a的结果,b已变成3)
(∧)a=111(2)
a=100(2)(a∧b的结果,a已变成4)
等效于以下两步:
① 执行前两个赋值语句:“a=a∧b;”和“b=b∧a;”相当于b=b∧(a∧b)。
② 再执行第三个赋值语句: a=a∧b。由于a的值等于(a∧b),b的值等于(b∧a∧b),
因此,相当于a=a∧b∧b∧a∧b,即a的值等于a∧a∧b∧b∧b,等于b。
二 移位操作符
移位操作符的运算对象也是二进制的"位"。移位操作符只可用来处理整数类型。左移位操作符(<<)能按照操作符右侧指定的位数将操作符左边的操作数向左移动(在低位补0)。
"有符号"右移位操作符(>>)则按照操作符右侧指定的位数将操作符左边的操作数向右移动。"有符号"右移位操作符使用"符号扩展":若符号为正,则在高位插入0;若符号位负,则在高位插入1.
Java中增加了一种"无符号"右移位操作符(>>>),它使用了"零扩展":无论正负,都在高位插入0。这一操作符在C或C++是没有的。
注意:如果对byte或short值进行这样的移位运算,得到的可能不是正确结果。它们会先被转化成int类型,再进行右移操作,然后被截断,赋值给原来的类型,在这种情况下只能得到-1的结果。
扩展:Java中的基本数据类型长度的大小不会因操作系统环境而改变,这也就是java能提高可移植性的优点。
下面做个练习:
编写一个方法,来代替java中的Integer.toBinaryString()。(提示:用三元操作符和按位操作符来显示二进制的1和0)
参考答案:
/**
*
*/
package 控制执行流程;
/**
* @author Administrator
*
*/
public class Exercise4_5 {
/**
* 将整型转化成二进制形式输出
* @param n
*/
public static void change(byte n){
byte length=0;
int copy=n;
System.out.println(copy);
copy=( copy&0xff);
while(copy>0){//求二进制有效数字的长度
length++;
copy=(byte)(copy>>1);
}
System.out.println("length:"+length);
for(int i=length;i>0;i--){//输出二进制
if((n&(1<<(i-1)))>0){
System.out.print(1);
}
else
System.out.print(0);
}
System.out.println();
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
byte a=(byte)0xAA;
byte b=(byte)0x55;
//测试:
System.out.println(Integer.toBinaryString(a));
System.out.println(Integer.toBinaryString(b));
change(a);
change(b);
}
}