介绍
移位运算符是java基本运算符中的一种,是用来对二进制表示的数字进行位移操作的,可以用于整型变量(byte、short、int、long)和字符型变量(char)——对char类型进行移位运算符计算时,会默认先转为int类型再进行移位计算。
以下正数例子默认用int类型的数字6的补码来计算:
0000 0000 0000 0000 0000 0000 0000 0110
以下负数例子默认用int类型的数字-6的补码来计算:
1111 1111 1111 1111 1111 1111 1111 1010
————复习正负数转换的补码运算
负数的补码表示是将其对应的正数的补码中的每一位取反,然后再加上1
取反得到:
1111 1111 1111 1111 1111 1111 1111 1001
然后加上1:
1111 1111 1111 1111 1111 1111 1111 1010
左移运算符 <<
规则:相当于把变量的二进制补码的所有位全部左移一个位置,数学意义是值*2
6<<1
左移前:0000 0000 0000 0000 0000 0000 0000 0110
左移后:0000 0000 0000 0000 0000 0000 0000 1100
结果:十进制的6变为12
-6<<1
左移前:1111 1111 1111 1111 1111 1111 1111 1010
左移后:1111 1111 1111 1111 1111 1111 1111 0100
左移后的结果转为原码:1000 0000 0000 0000 0000 0000 0000 1100
结果:十进制的-6变为-12
带符号右移运算符 >>
规则:相当于把变量的二进制补码的所有位全部右移一个位置,注意此时因为是带符号的右移,正数的高位补0,负数的高位补1,数学意义是值/2
6>>1
右移前:0000 0000 0000 0000 0000 0000 0000 0110
右移后:0000 0000 0000 0000 0000 0000 0000 0011
结果:十进制的6变为3
-6>>1
右移前:1111 1111 1111 1111 1111 1111 1111 1010
右移后:1111 1111 1111 1111 1111 1111 1111 1101
右移后的结果转为原码:1000 0000 0000 0000 0000 0000 0000 0011
结果:十进制的-6变为-3
无符号右移运算符 >>>
规则:相当于把变量的二进制补码的所有位全部右移一个位置,但因为是无符号的右移,正数的高位补0,负数的高位也补0!此时的数学意义不一定存在
6>>>1
右移前:0000 0000 0000 0000 0000 0000 0000 0110
右移后:0000 0000 0000 0000 0000 0000 0000 0011
结果:十进制的6变为3
-6>>>1
右移前:1111 1111 1111 1111 1111 1111 1111 1010
右移后:0111 1111 1111 1111 1111 1111 1111 1101(变为了正数)
结果:十进制的-6变为231-1-2也就是231-3
一些思考
1.移位运算符的操作数大小有限制吗?(考虑到整型二进制的位数是确定的)
有,对于int类型来说,4个字节,32位,所以使用移位运算符时,如果操作数是<<33,则相当于<<1;对于byte类型来说,1个字节,8位,如果操作数是<<9,则相当于<<1——也就是说需要操作数%位数。
2.java中使用移位运算符的场景
- 性能优化:位移运算符通常比乘除法和取模运算更快。在某些情况下,使用位移运算符可以提高代码的性能,尤其是当需要进行大量的乘法或除法运算时。
- 位操作:位移运算符可以方便地对二进制位进行操作。例如,可以使用位移运算符从整数中提取特定的位,设置位或清除位。
- 掩码操作:位移运算符可以与位掩码一起使用,用于对数据的特定位进行操作或提取。通过使用位掩码和位移运算符,可以方便地对数据进行分割、筛选或合并。
- 效率和资源节约:在一些特定的场景中,位移运算符可以用来节约内存或其他资源。例如,使用位移运算符可以有效地对数据进行压缩或编码。
- 位级算术:位移运算符可以用于实现一些位级算术操作,如乘以2的幂、除以2的幂等。这在一些算法和数据结构中非常有用,如位图、哈希表等。
————————
以上为个人学习记录,如有错误,还请指正