经常在一些算法中看到 num >>> 1的写法,num >>> 1,相当于num除以2,为什么不直接写num除以2呢?因为计算机中的数据是以二进制的形式存储的,数学运算的加减乘除底层也是二进制移位实现的,直接在二进制上移位,显然要比数学运算来的更直接。
来看一下Java中的移位运算符,有三种:
<<
: 左移运算符,num << 1,相当于num乘以2
>>
: 右移运算符,num >> 1,相当于num除以2
>>>
: 无符号右移运算符,num >>> 1,相当于num除以2,忽略符号位,空位都以0补齐
示例:
int num = 8;
int num1 = num << 1; //num1 = 16
int num2 = num >> 1 ; //num2 = 4
int num3 = num >>> 1; //num3 = 4
注意:无符号右移运算符忽略了最高位的符号位,0补最高位,并且无符号右移运算符 >>> 只对32位和64位的数值有意义。Java中只有这三种位移,没有向左的无符号位移。
int num = -8;
int num1 = num << 1; //num1 = -16
int num2 = num >> 1 ; //num2 = -4
int num3 = num >>> 1; //num3 = 21 4748 3644
为什么 num3 是 21 4748 3644 这么个数?因为数值在计算机中是以补码的形式的存储的,-8的补码是 [11111111 11111111 11111111 11111000],右移一位则变成了 [01111111 11111111 11111111 11111100],最高位的1表示负数,0表示正数,>>>
时0补最高位的符号位,[01111111 11111111 11111111 11111100] 的十进制就是21 4748 3644。在正数位移的时候,>>
和 >>>
是一样的,在负数位移的时候就不一样了。
Java算法中的 >>>1 与 /2 是等效的,前者运算效率高,后者运算级别高。
网友评论