在Think in Java中有这么一段话“对char,byte或者short进行移位处理,那么在移位进行之前,它们会自动转换成一个int。只有右侧的5个低位才会有用。这样可防止我们在一个int数里移动不切实际的位数。若对一个long值进行处理,最后得到的结果也是long。此时只会用到右侧的6个低位,防止移动超过long值里现成的位数。”
对上面那段话的理解是:移位操作符操作的运算对象是二进制的“位”,int类型是32位也就是2的5次幂 !如果移32位以上,那么原来的数的信息会全部丢失,这样也就没有什么意义了!所以上面的“只有右侧的5个低位才会有用”说的是:移位操作符右端的那个数(化成二进制)的低5位才有用,即
X < <y;
是指y的低5位才有用,即不能大于32。 而对于long型也是同样的道理!
1 package com.xingle_test.operator; 2 3 /** 4 * 5 * @ClassName: shifting 移位操作 6 * @author Xingle 7 * @date 2014-7-22 上午9:30:16 8 */ 9 public class shifting { 10 11 public static void main(String[] args) { 12 int i = 1; 13 pBinInt("" + i + "", i); 14 int i_1 = i << 2; 15 pBinInt("<<2", i_1); 16 int i_2 = i << 34; 17 pBinInt("<<34", i_2); 18 System.out.println(); 19 20 int k = -1; 21 pBinInt("" + k + "", k); 22 int k_1 = k << 2; 23 pBinInt("<<2", k_1); 24 int k_2 = k << 34; 25 pBinInt("<<34", k_2); 26 System.out.println(); 27 28 long j = -12; 29 pBinLong("" + j + "", j); 30 long j_1 = j >> 2; 31 pBinLong(">>2", j_1); 32 long j_2 = j >> 66; 33 pBinLong(">>66", j_2); 34 System.out.println(); 35 36 } 37 38 /** 39 * long 打印二进制 40 * 41 * @param s 42 * @param j 43 * @author xingle 44 * @data 2014-7-22 上午9:41:17 45 */ 46 private static void pBinLong(String s, long l) { 47 System.out.println(s + ", long: " + l + ", binary: "); 48 System.out.print(" "); 49 for (int i = 63; i >= 0; i--) 50 if (((1L << i) & l) != 0) 51 System.out.print("1"); 52 else 53 System.out.print("0"); 54 System.out.println(); 55 } 56 57 /** 58 * int 打印二进制 59 * 60 * @param s 61 * @param i 62 * @author xingle 63 * @data 2014-7-22 上午9:31:42 64 */ 65 private static void pBinInt(String s, int i) { 66 System.out.println(s + ", int: " + i + ", binary: "); 67 System.out.print(" "); 68 for (int j = 31; j >= 0; j--) 69 if (((1 << j) & i) != 0) 70 System.out.print("1"); 71 else 72 System.out.print("0"); 73 System.out.println(); 74 } 75 76 }
执行结果:
1, int: 1, binary:
00000000000000000000000000000001
<<2, int: 4, binary:
00000000000000000000000000000100
<<34, int: 4, binary:
00000000000000000000000000000100
-1, int: -1, binary:
11111111111111111111111111111111
<<2, int: -4, binary:
11111111111111111111111111111100
<<34, int: -4, binary:
11111111111111111111111111111100
-12, long: -12, binary:
1111111111111111111111111111111111111111111111111111111111110100
>>2, long: -3, binary:
1111111111111111111111111111111111111111111111111111111111111101
>>66, long: -3, binary:
1111111111111111111111111111111111111111111111111111111111111101
从以上结可以看到对于32位的int型,左移2位和左移34位的结果是相同的;
对于long型,左移2位和左移66位的结果是一样的。
在java中无论左移右移,会遵循下面的规则
value<<n(其中value为int,n>=0) 等价于 value<<(n%32)
value>>n (其中value为int,n>=0) 等价于 value>>(n%32)
value>>>n (其中value为int,n>=0) 等价于 value>>>(n%32)
对于long类型的:
value<<n(其中value为long,n>=0) 等价于 value<<(n%64)
value>>n (其中value为long,n>=0) 等价于 value>>(n%64)
value>>>n (其中value为long,n>=0) 等价于 value>>>(n%64)
1 /** 2 * @Title: shifting.java 3 * @Description: TODO 4 * @author :Xingle 5 * @date 2014-7-22 上午9:30:16 6 * @version 7 */ 8 9 package com.xingle_test.operator; 10 11 /** 12 * 13 * @ClassName: shifting 移位操作 14 * @author Xingle 15 * @date 2014-7-22 上午9:30:16 16 */ 17 public class shifting { 18 19 public static void main(String[] args) { 20 21 int i = 100; 22 pBinInt("" + i + "", i); 23 int i_1 = i << -38; 24 pBinInt("<<-38", i_1); 25 int i_2 = i << 26; 26 pBinInt("<<26", i_2); 27 System.out.println(); 28 29 int k = -100; 30 pBinInt("" + k + "", k); 31 int k_1 = k << -38; 32 pBinInt("<<-38", k_1); 33 int k_2 = k << 26; 34 pBinInt("<<26", k_2); 35 System.out.println(); 36 37 long j = 12; 38 pBinLong("" + j + "", j); 39 long j_1 = j << -3; 40 pBinLong("<<-3", j_1); 41 long j_2 = j << 61; 42 pBinLong("<<61", j_2); 43 System.out.println(); 44 45 long a = -112; 46 pBinLong("" + a + "", a); 47 long a_1 = a >>> -67; 48 pBinLong(">>> -67", a_1); 49 long a_2 = a >>> 61; 50 pBinLong(">>> 61", a_2); 51 System.out.println(); 52 53 } 54 55 /** 56 * long 打印二进制 57 * 58 * @param s 59 * @param j 60 * @author xingle 61 * @data 2014-7-22 上午9:41:17 62 */ 63 private static void pBinLong(String s, long l) { 64 System.out.println(s + ", long: " + l + ", binary: "); 65 System.out.print(" "); 66 for (int i = 63; i >= 0; i--) 67 if (((1L << i) & l) != 0) 68 System.out.print("1"); 69 else 70 System.out.print("0"); 71 System.out.println(); 72 } 73 74 /** 75 * int 打印二进制 76 * 77 * @param s 78 * @param i 79 * @author xingle 80 * @data 2014-7-22 上午9:31:42 81 */ 82 private static void pBinInt(String s, int i) { 83 System.out.println(s + ", int: " + i + ", binary: "); 84 System.out.print(" "); 85 for (int j = 31; j >= 0; j--) 86 if (((1 << j) & i) != 0) 87 System.out.print("1"); 88 else 89 System.out.print("0"); 90 System.out.println(); 91 } 92 93 }
执行结果:
100, int: 100, binary:
00000000000000000000000001100100
<<-38, int: -1879048192, binary:
10010000000000000000000000000000
<<26, int: -1879048192, binary:
10010000000000000000000000000000
-100, int: -100, binary:
11111111111111111111111110011100
<<-38, int: 1879048192, binary:
01110000000000000000000000000000
<<26, int: 1879048192, binary:
01110000000000000000000000000000
12, long: 12, binary:
0000000000000000000000000000000000000000000000000000000000001100
<<-3, long: -9223372036854775808, binary:
1000000000000000000000000000000000000000000000000000000000000000
<<61, long: -9223372036854775808, binary:
1000000000000000000000000000000000000000000000000000000000000000
-112, long: -112, binary:
1111111111111111111111111111111111111111111111111111111110010000
>>> -67, long: 7, binary:
0000000000000000000000000000000000000000000000000000000000000111
>>> 61, long: 7, binary:
0000000000000000000000000000000000000000000000000000000000000111
由以上可以看出:
对于int,左移-38和左移26是相等的;
对于long,左移-3和左移61是相等的;
对于无符号右移,右移-67和右移61是相等的;
结论:
value << -n(value为int,n>=0) 等价于 value << (-n & 31)
value >> -n(value为int,n>=0) 等价于 value >> (-n & 31)
value >>> -n(value为int,n>=0) 等价于 value >>> (-n & 31)
而对于long
value << -n(value为long,n>=0) 等价于 value << (-n & 63)
value >> -n(value为long,n>=0) 等价于 value >> (-n & 63)
value >>> -n(value为long,n>=0) 等价于 value >>> (-n & 63)