一.Java位运算
1.表示方法:
  在Java语言中,二进制数使用补码表示,最高位为符号位,正数的符号位为0,负数的符号位为1,补码的表示满足如下条件:
  (1)正数的最高位为0,其余各位代表数值本身(二进制数)。  
  (2)对于负数,通过对该数绝对值的补码按位取反,再对整个数加1。
2.位运算符 
  位运算表达式由操作数和位运算符组成,实现对整数类型的二进制数进行位运算。位运算符可以分为逻辑运算符(包括~、&、|和^)及移位运算符(包括>>、<<和>>>)。 
  1)左移位运算符(<<)能将运算符左边的运算对象向左移动运算符右侧指定的位数(在低位补0)。 
  2)“有符号”右移位运算符(>>)则将运算符左边的运算对象向右移动运算符右侧指定的位数。 “有符号”右移位运算符使用了“符号扩展”:若值为正,则在高位插入0;若值为负,则在高位插入1。
  3)Java也添加了一种“无符号”右移位运算符(>>>),它使用了“零扩展”:无论正负,都在高位插入0。这一运算符是C或C++没有的。 
  4)若对char,byte或者short进行移位处理,那么在移位进行之前,它们会自动转换成一个int。 只有右侧的5个低位才会用到。这样可防止我们在一个int数里移动不切实际的位数。 若对一个long值进行处理,最后得到的结果也是long。此时只会用到右侧的6个低位,防止移动超过long值里现成的位数。 但在进行“无符号”右移位时,也可能遇到一个问题。若对byte或short值进行右移位运算,得到的可能不是正确的结果(Java 1.0和Java 1.1特别突出)。 它们会自动转换成int类型,并进行右移位。但“零扩展”不会发生,所以在那些情况下会得到-1的结果。 


  在进行位运算时,需要注意以下几点。   
  (1)>>>和>>的区别是:在执行运算时,>>>运算符的操作数高位补0,而>>运算符的操作数高位移入原来高位的值。   
  (2)右移一位相当于除以2,左移一位(在不溢出的情况下)相当于乘以2;移位运算速度高于乘除运算。   
  (3)若进行位逻辑运算的两个操作数的数据长度不相同,则返回值应该是数据长度较长的数据类型。   
  (4)按位异或可以不使用临时变量完成两个值的交换,也可以使某个整型数的特定位的值翻转。   
  (5)按位与运算可以用来屏蔽特定的位,也可以用来取某个数型数中某些特定的位。   
  (6)按位或运算可以用来对某个整型数的特定位的值置l。
3.位运算符的优先级  
   ~的优先级最高,其次是<<、>>和>>>,再次是&,然后是^,优先级最低的是|。 
4.运算符的使用
  1)<<

public class Test {  
    public static void main(String[] args) {  
       System.out.println(5<<2);//运行结果是20  
    }  
}  
    0000 0000 0000 0000 0000 0000 0000 0101  然后左移2位后,低位补0:    0x00,0x00,0x00,0x05
    0000 0000 0000 0000 0000 0000 0001 0100  换算成10进制为20




  2)>>


    

System.out.println(5>>2);//运行结果是1
    0000 0000 0000 0000 0000 0000 0000 0101 然后右移2位,高位补0:
    0000 0000 0000 0000 0000 0000 0000 0001




  3)>>>


    

public class Test {  
    public static void main(String[] args) {  
        System.out.println(5>>3);//结果是0  
        System.out.println(-5>>3);//结果是-1  
        System.out.println(-5>>>3);//结果是536870911  
    }  
} 


    5换算成二进制: 0000 0000 0000 0000 0000 0000 0000 0101
    5右移3位后结果为0,0的二进制为: 0000 0000 0000 0000 0000 0000 0000 0000        // (用0进行补位)
   -5换算成二进制补码: 1111 1111 1111 1111 1111 1111 1111 1011
   -5右移3位后结果为-1,-1的二进制为: 1111 1111 1111 1111 1111 1111 1111 1111   // (用1进行补位)
   -5无符号右移3位后的结果 536870911 换算成二进制:0001 1111 1111 1111 1111 1111 1111 1111   // (用0进行补位)






   负数的补码为 绝对值取反加1  


   负数的原码为 补码除符号位减1取反 1111 1111 1111 1111 1111 1111 1111 1110-> 1000 0000 0000 0000 0000 0000 0000 0001




   通过其结果转换成二进制后,我们可以发现,正数右移,高位用0补,负数右移,高位用1补,当负数使用无符号右移时,用0进行部位(自然而然的,就由负数变成了正数了)


   注意:笔者在这里说的是右移,高位补位的情况。正数或者负数左移,低位都是用0补。(自行测试)


  4)&


    

public class Test {  
   public static void main(String[] args) {  
       System.out.println(5 & 3);//结果为1  
   }  
    }
    5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
    3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011


--------------------------------------------------------
与运算结果:   0000 0000 0000 0000 0000 0000 0000 0001




  5)|

public class Test {  
   public static void main(String[] args) {  
       System.out.println(5 | 3);//结果为7  
   }  
}  
    5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
    3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011


--------------------------------------------------------
或运算结果:   0000 0000 0000 0000 0000 0000 0000 0111




  6)^

public class Test {  
    public static void main(String[] args) {  
        System.out.println(5 ^ 3);//结果为6  
    }  
}
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011


--------------------------------------------------------
异或运算结果: 0000 0000 0000 0000 0000 0000 0000 0110




  7)~

public class Test {  
    public static void main(String[] args) {  
        System.out.println(~5);//结果为-6  
    }  
} 
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101


-------------------------------------------------------
    非运算结:     1111 1111 1111 1111 1111 1111 1111 1010