【Java】Java中的位移运算

以下分析仅针对Java语言,结论在最下面。

一、左移(<<):高位舍弃,低位补0

  代码(初始为正数1,连续左移,直到为0)
		int n = 1;
		int step = 1;
		System.out.println(step + ":" + Integer.toBinaryString(n) + ":" + n);
		while (n != 0) {
			n = n << 1;
			step++;
			System.out.println(step + ":" + Integer.toBinaryString(n) + ":" + n);
		}
  运行结果
1:1:1
2:10:2
3:100:4
4:1000:8
5:10000:16
6:100000:32
7:1000000:64
8:10000000:128
9:100000000:256
10:1000000000:512
11:10000000000:1024
12:100000000000:2048
13:1000000000000:4096
14:10000000000000:8192
15:100000000000000:16384
16:1000000000000000:32768
17:10000000000000000:65536
18:100000000000000000:131072
19:1000000000000000000:262144
20:10000000000000000000:524288
21:100000000000000000000:1048576
22:1000000000000000000000:2097152
23:10000000000000000000000:4194304
24:100000000000000000000000:8388608
25:1000000000000000000000000:16777216
26:10000000000000000000000000:33554432
27:100000000000000000000000000:67108864
28:1000000000000000000000000000:134217728
29:10000000000000000000000000000:268435456
30:100000000000000000000000000000:536870912
31:1000000000000000000000000000000:1073741824
32:10000000000000000000000000000000:-2147483648
33:0:0

  从第31到第32行可以看出,符号位上的0被右边左移过来的1覆盖了,使数字变成了负数;类似地,从第32到第33行可以看出,符号位又被覆盖成了0。

  代码(初始为负数-2147483647,连续左移,直到为0)
		int n = -2147483647;
		int step = 1;
		System.out.println(step + ":" + Integer.toBinaryString(n) + ":" + n);
		while (n != 0) {
			n = n << 1;
			step++;
			System.out.println(step + ":" + Integer.toBinaryString(n) + ":" + n);
		}
  运行结果
1:10000000000000000000000000000001:-2147483647
2:10:2
3:100:4
4:1000:8
5:10000:16
6:100000:32
7:1000000:64
8:10000000:128
9:100000000:256
10:1000000000:512
11:10000000000:1024
12:100000000000:2048
13:1000000000000:4096
14:10000000000000:8192
15:100000000000000:16384
16:1000000000000000:32768
17:10000000000000000:65536
18:100000000000000000:131072
19:1000000000000000000:262144
20:10000000000000000000:524288
21:100000000000000000000:1048576
22:1000000000000000000000:2097152
23:10000000000000000000000:4194304
24:100000000000000000000000:8388608
25:1000000000000000000000000:16777216
26:10000000000000000000000000:33554432
27:100000000000000000000000000:67108864
28:1000000000000000000000000000:134217728
29:10000000000000000000000000000:268435456
30:100000000000000000000000000000:536870912
31:1000000000000000000000000000000:1073741824
32:10000000000000000000000000000000:-2147483648
33:0:0

  从第1到第2行可以看出,符号位上的1被右边左移过来的0覆盖了,使数字变成了正数;类似地,从第31到第32行可以看出,符号位又被覆盖成了1;类似地,从第32到第33行可以看出,符号位又被覆盖成了0。

二、右移(>>):高位补符号位,低位舍弃

  代码(初始为正数2147483647,连续右移,直到为0)
		int n = 2147483647;
		int step = 1;
		System.out.println(step + ":" + Integer.toBinaryString(n) + ":" + n);
		while (n != 0) {
			n = n >> 1;
			step++;
			System.out.println(step + ":" + Integer.toBinaryString(n) + ":" + n);
		}
  运行结果
1:1111111111111111111111111111111:2147483647
2:111111111111111111111111111111:1073741823
3:11111111111111111111111111111:536870911
4:1111111111111111111111111111:268435455
5:111111111111111111111111111:134217727
6:11111111111111111111111111:67108863
7:1111111111111111111111111:33554431
8:111111111111111111111111:16777215
9:11111111111111111111111:8388607
10:1111111111111111111111:4194303
11:111111111111111111111:2097151
12:11111111111111111111:1048575
13:1111111111111111111:524287
14:111111111111111111:262143
15:11111111111111111:131071
16:1111111111111111:65535
17:111111111111111:32767
18:11111111111111:16383
19:1111111111111:8191
20:111111111111:4095
21:11111111111:2047
22:1111111111:1023
23:111111111:511
24:11111111:255
25:1111111:127
26:111111:63
27:11111:31
28:1111:15
29:111:7
30:11:3
31:1:1
32:0:0
  代码(初始为负数-2147483648,连续右移,直到为-1)
		int n = -2147483648;
		int step = 1;
		System.out.println(step + ":" + Integer.toBinaryString(n) + ":" + n);
		while (n != -1) {
			n = n >> 1;
			step++;
			System.out.println(step + ":" + Integer.toBinaryString(n) + ":" + n);
		}
  运行结果
1:10000000000000000000000000000000:-2147483648
2:11000000000000000000000000000000:-1073741824
3:11100000000000000000000000000000:-536870912
4:11110000000000000000000000000000:-268435456
5:11111000000000000000000000000000:-134217728
6:11111100000000000000000000000000:-67108864
7:11111110000000000000000000000000:-33554432
8:11111111000000000000000000000000:-16777216
9:11111111100000000000000000000000:-8388608
10:11111111110000000000000000000000:-4194304
11:11111111111000000000000000000000:-2097152
12:11111111111100000000000000000000:-1048576
13:11111111111110000000000000000000:-524288
14:11111111111111000000000000000000:-262144
15:11111111111111100000000000000000:-131072
16:11111111111111110000000000000000:-65536
17:11111111111111111000000000000000:-32768
18:11111111111111111100000000000000:-16384
19:11111111111111111110000000000000:-8192
20:11111111111111111111000000000000:-4096
21:11111111111111111111100000000000:-2048
22:11111111111111111111110000000000:-1024
23:11111111111111111111111000000000:-512
24:11111111111111111111111100000000:-256
25:11111111111111111111111110000000:-128
26:11111111111111111111111111000000:-64
27:11111111111111111111111111100000:-32
28:11111111111111111111111111110000:-16
29:11111111111111111111111111111000:-8
30:11111111111111111111111111111100:-4
31:11111111111111111111111111111110:-2
32:11111111111111111111111111111111:-1

三、无符号右移(>>>):低位舍弃,高位补0

  代码(初始为正数2147483647,连续无符号右移,直到为0)
		int n = 2147483647;
		int step = 1;
		System.out.println(step + ":" + Integer.toBinaryString(n) + ":" + n);
		while (n != 0) {
			n = n >>> 1;
			step++;
			System.out.println(step + ":" + Integer.toBinaryString(n) + ":" + n);
		}
  运行结果
1:1111111111111111111111111111111:2147483647
2:111111111111111111111111111111:1073741823
3:11111111111111111111111111111:536870911
4:1111111111111111111111111111:268435455
5:111111111111111111111111111:134217727
6:11111111111111111111111111:67108863
7:1111111111111111111111111:33554431
8:111111111111111111111111:16777215
9:11111111111111111111111:8388607
10:1111111111111111111111:4194303
11:111111111111111111111:2097151
12:11111111111111111111:1048575
13:1111111111111111111:524287
14:111111111111111111:262143
15:11111111111111111:131071
16:1111111111111111:65535
17:111111111111111:32767
18:11111111111111:16383
19:1111111111111:8191
20:111111111111:4095
21:11111111111:2047
22:1111111111:1023
23:111111111:511
24:11111111:255
25:1111111:127
26:111111:63
27:11111:31
28:1111:15
29:111:7
30:11:3
31:1:1
32:0:0
  代码(初始为负数-1,连续无符号右移,直到为0)
		int n = -1;
		int step = 1;
		System.out.println(step + ":" + Integer.toBinaryString(n) + ":" + n);
		while (n != 0) {
			n = n >>> 1;
			step++;
			System.out.println(step + ":" + Integer.toBinaryString(n) + ":" + n);
		}
  运行结果
1:11111111111111111111111111111111:-1
2:1111111111111111111111111111111:2147483647
3:111111111111111111111111111111:1073741823
4:11111111111111111111111111111:536870911
5:1111111111111111111111111111:268435455
6:111111111111111111111111111:134217727
7:11111111111111111111111111:67108863
8:1111111111111111111111111:33554431
9:111111111111111111111111:16777215
10:11111111111111111111111:8388607
11:1111111111111111111111:4194303
12:111111111111111111111:2097151
13:11111111111111111111:1048575
14:1111111111111111111:524287
15:111111111111111111:262143
16:11111111111111111:131071
17:1111111111111111:65535
18:111111111111111:32767
19:11111111111111:16383
20:1111111111111:8191
21:111111111111:4095
22:11111111111:2047
23:1111111111:1023
24:111111111:511
25:11111111:255
26:1111111:127
27:111111:63
28:11111:31
29:1111:15
30:111:7
31:11:3
32:1:1
33:0:0

四、结论

  1、所有的位移运算都是所有位一起移动,移出去的位舍弃,空出来的位可能补0或1。
  2、左移运算:低位补0,高位舍弃(符号位被舍弃了)。若一直左移,数字最终会变为0。
  3、右移运算:低位舍弃,高位补符号位(符号位也右移了,但又补上了符号位,相当于符号位被保留了)。若一直右移,正数最终变为0,负数最终变为-1。
  4、无符号右移运算:低位舍弃,高位补0(符号位右移了,不再是符号位)。若一直无符号右移,数字最终会变为0。

五、为什么没有无符号左移运算?

  个人认为,符号位在最高位,右移使符号位出现空位需要补位时,才会考虑补0还是补1的问题,因为这会影响数字的正负;而左移是最低位需要补位,自然是补0,补1是没有意义的(也可以说,无论补0还是补1只是一个约定,因为不会影响正负)。

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值