首页 > 代码库 > think in java 读书笔记 1 ——移位
think in java 读书笔记 1 ——移位
在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 s42 * @param j43 * @author xingle44 * @data 2014-7-22 上午9:41:1745 */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 else53 System.out.print("0");54 System.out.println();55 }56 57 /**58 * int 打印二进制59 * 60 * @param s61 * @param i62 * @author xingle63 * @data 2014-7-22 上午9:31:4264 */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 else72 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 Xingle15 * @date 2014-7-22 上午9:30:1616 */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 s59 * @param j60 * @author xingle61 * @data 2014-7-22 上午9:41:1762 */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 else70 System.out.print("0");71 System.out.println();72 }73 74 /**75 * int 打印二进制76 * 77 * @param s78 * @param i79 * @author xingle80 * @data 2014-7-22 上午9:31:4281 */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 else89 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)