首页 > 代码库 > 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)