banner
NEWS LETTER

Java中的移位运算

Scroll down

前言

Java中的移位操作主要包括三种:<<(左移)、>>(有符号右移)、>>>(无符号右移)。这三种移位操作都只能作用于longintshortbytechar这五种基本的整型类型上,由于 doublefloat 在二进制中的表现比较特殊,因此不能来进行移位操作。通常情况下,移位操作比普通运算的效率更高。

左移 <<

左移运算是将数据的二进制数向左移动若干位,高位丢弃,低位补零,如:

1
2
3
4
5
6
7
8
int a = -1;
a <<= 10;

// a的二进制数:
//11111111 11111111 11111111 11111111
//向左移动10位,高位丢弃,低位补零:
//11111111 11111111 11111100 00000000
//结果是a = -1024

有符号右移 >>

有符号右移是将数据的二进制数向右移动若干位,低位丢弃,高位补符号位,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int a = 8;
a >>= 3;
// a的二进制数:
//00000000 00000000 00000000 00001000
//向右移动10位,低位丢弃,高位补0
//00000000 00000000 00000000 00000001
//结果是a = 1
int b =-8;
b >>= 3;
// b的二进制数:
//11111111 11111111 11111111 11111000
//向右移动10位,低位丢弃,高位补1
//11111111 11111111 11111111 11111111
//结果是b = -1

无符号右移 >>>

无符号右移是将数据的二进制数向右移动若干位,低位丢弃,高位补0,如:

1
2
3
4
5
6
7
int b =-8;
b >>= 3;
// b的二进制数:
//11111111 11111111 11111111 11111000
//向右移动10位,低位丢弃,高位补0
//00011111 11111111 11111111 11111111
//结果是b = 536870911

可以发现正数的>>和>>>是等价的

对 short、byte、char 的移位操作

java对short、byte和char的移位操作,首先会将其补成32位的int型,再对其进行移位操作,最后低位截取对应的位数,比如:

1
2
3
4
5
6
7
8
9
10
11
byte a = -2;
System.out.println(a >>> 1);
//首先将8位的a转成32位
//11111110 -> 11111111 11111111 11111111 11111110
//对这32位int进行移位,此时是无符号右移1位,高位补0
//01111111 11111111 11111111 11111111
//注意此时并没有赋值号,因此直接输出该32位的结果
//输出结果为:2147483647
System.out.println(a >>= 1);
//此时有赋值号,将移位后的结果截取低8位,即11111111
//输出结果为:-1

注意,如果输出a >> 3,此时不会对结果进行截取。只有a >>= 3,即对a赋值的时候才会进行低位截取,比如此时a是byte类型,在java中占8位,就对移位后的结果取低8位赋给a

移位的位数超过数值所占有的位数

对于要移动的位数i,如果i超过了该类型数值所占位数j,则取i%j的结果作为最终要移动的位数,其中short、byte和char类型总是会先转化为32位int,比如:

1
2
3
4
5
6
7
8
byte c = 1;
System.out.println(c >>> 8);
System.out.println(c >>> 32);
System.out.println(c >>> 33);
//输出结果:
// 0
// 1
// 0