java 学习笔记之位移运算符

位移运算符以前一直没怎么注意,今天因为某些原因使用了一下,结果跟预期不一样,所以回头看了一下,最终发现在使用的时候还是有一些注意事项的。

java中提供了3个位移运算符:
1.带符号的右移运算符(>>):将运算符左边的运算对象向右移动运算符右侧指定的位数。“有符号”右移位运算符使用了“符号扩展”:若值为正,则在高位插入 0;若值为负,则在高位插入 1 。
2.带符号的左移运算符(<<):将运算符左边的运算对象向左移动运算符右侧指定的位数(在低位补 0) 。
3.不带符号的右移运算符(>>>):将运算符左边的运算对象向右移动运算符右侧指定的位数。它使用了“零扩展”:无论正负,都在高位插入0 。
我个人是有点儿奇怪为什么没有不带符号的左移运算符呢0-0

首先要明确一点的是,位移运算符进行运算的时候,针对的是数字的补码,这点首先要搞清楚,刚开始我一直在用源码进行推算,所以结果一直出错,表示非常尴尬。如果你不知道原码,补码,反码的概念,可能你需要查找一下相关的资料了解一下(原码,补码,反码)。

 

package test;

public class Test {
	public static void main(String[] args) {
		
		//11111111 11111111 11111111 11111111
		int i = -1;   
		//00000000 00111111 11111111 11111111
		i >>>= 10;     
		//4194303
		System.out.println("-1(int) >>> 10 : "+i);  
		
		//11111111 11111111 11111111 11111111 111111111 11111111 11111111 11111111
		long l = -1;
		//00000000 00111111 11111111 11111111 111111111 11111111 11111111 11111111
		l >>>= 10;
		//18014398509481983
		System.out.println("-1(long) >>> 10 : "+l);
		
		//short,char,byte进行位运算时都会先转换成int型,刚开始不知道这点,纠结了好久。
		//11111111 11111111 11111111 11111111 
		short s = -1;
		//00000000 00000000 01111111 11111111 
		s >>>= 17;
		System.out.println("-1(short) >>> 17 : "+s);
		
		//11111111 11111111 11111111 11111111
		byte b = -1;
		//11111111 11111111 11111111 11111111
		b >>= 26;
		//-1
		System.out.println("-1(byte) >> 26 : "+b);
	}
}

综上,有几点需要注意:

 

1。位运算是针对数值的补码来进行的。

2。short,char,byte进行位运算时,需要先将其转换成对应的int型再进行运算。

3.若对 byte 或 short 值进行右移位运算,得到的可能不是正确的结果。它们会自动转换成 int 类型,并进行右移位。但“零扩展”不会发生,所以在那些情况下会得到-1 的结果 。

下面有个通过位移符来实现的输出一个int数值的二进制的方法,可以加深一下学习:

 

public void printBinInt(String s, int i) {
    System.out.println(s + ", int: " + i + ", binary: ");
    System.out.print(" ");
    //通过循环,用1与数字的每一位相与,从而得出当前位的值是0还是1
    for(int j = 31; j >=0; j--){
        if(((1 << j) & i) != 0)
            System.out.print("1");
        else
            System.out.print("0");
   }
   System.out.println();
}


以上为本篇内容

 

posted @ 2017-08-29 10:41  moonfish  阅读(311)  评论(0编辑  收藏  举报