一篇文章让你学会Java之左移、右移操作

左移和右移

  • 1. 左移运算符(`<<`)
  • 功能:
  • 语法:
  • 特点:
  • 示例:
  • 2. 右移运算符(`>>`)
  • 功能:
  • 语法:
  • 特点:
  • 示例:
  • 3. 无符号右移运算符(`>>>`)
  • 示例:
  • 总结
  • 扩展:`i <<= j`
  • 运算过程
  • 示例
  • 示例1:对正数进行左移
  • 示例2:对负数进行左移
  • 示例3:可能的溢出问题
  • 注意点
  • 在Java中,左移 (
    <<) 和右移 (
    >>) 是位运算符,用于对二进制数进行移位操作。移位操作会对数字的位模式进行直接操作。


    1. 左移运算符(<<

    功能:

  • 左移操作会将一个数字的二进制位向左移动指定的位数,右边用 0 填充。
  • 每向左移动一位,相当于该数字乘以2(但不是严格意义上的乘法,可能会导致溢出)。
  • 语法:

    result = value << n;
    
  • value 是要操作的数字。
  • n 是移动的位数。
  • 特点:

  • 左移后会扩大数字的值(如果没有溢出的话)。
  • 右边补0。
  • 如果是负数,二进制会以补码形式参与计算。
  • 示例:

    int a = 5; // 二进制:00000000 00000000 00000000 00000101
    int result = a << 2; // 左移2位:00000000 00000000 00000000 00010100(20)
    System.out.println(result); // 输出:20
    

    2. 右移运算符(>>

    功能:

  • 右移操作会将一个数字的二进制位向右移动指定的位数。
  • 符号位扩展:如果是正数,高位用0填充;如果是负数,高位用1填充(即符号位保持不变)。
  • 每向右移动一位,相当于该数字除以2(向下取整)。
  • 语法:

    result = value >> n;
    
  • value 是要操作的数字。
  • n 是移动的位数。
  • 特点:

  • 对于正数,右移后高位用0填充。
  • 对于负数,右移后高位用1填充(符号位扩展)。
  • 适合处理带符号的数字。
  • 示例:

    int a = 20; // 二进制:00000000 00000000 00000000 00010100
    int result = a >> 2; // 右移2位:00000000 00000000 00000000 00000101(5)
    System.out.println(result); // 输出:5
    
    int b = -20; // 二进制:11111111 11111111 11111111 11101100(补码表示)
    int result2 = b >> 2; // 右移2位:11111111 11111111 11111111 11111011(-5)
    System.out.println(result2); // 输出:-5
    

    3. 无符号右移运算符(>>>

    除了 >>,Java 还提供了 无符号右移运算符 >>>

  • 无论正数还是负数,高位都用 0 填充。
  • 通常用于操作无符号数据。
  • 示例:

    int a = -20; // 二进制:11111111 11111111 11111111 11101100(补码表示)
    int result = a >>> 2; // 无符号右移2位:00111111 11111111 11111111 11111011
    System.out.println(result); // 输出:1073741819
    

    总结

    操作符 名称 功能
    << 左移 二进制向左移,右边补0,相当于乘以2的n次方(如果不溢出)。
    >> 符号右移 二进制向右移,保留符号位,高位补符号位(正数补0,负数补1),相当于除以2的n次方。
    >>> 无符号右移 二进制向右移,高位总是补0,不考虑符号位。

    扩展:i <<= j

  • 在Java中,i <<= j 是一个复合运算符,它等价于 i = i << j,表示将 i 的二进制位向左移动 j 位,然后将结果赋值给 i。即将 i 左移j位,相当于 i 乘以 2j 次方。
  • 运算过程

    1. i 的二进制形式会向左移动 j 位。
    2. 移位后,低位用 0 补充,高位可能会溢出(超出当前数据类型范围的部分会被丢弃)。
    3. 最终结果存回变量 i

    示例

    示例1:对正数进行左移

    public class Main {
        public static void main(String[] args) {
            int i = 5; // 二进制:00000000 00000000 00000000 00000101
            int j = 2;
    
            i <<= j; // 等价于 i = i << j
            // 左移2位:00000000 00000000 00000000 00010100 (20)
    
            System.out.println(i); // 输出:20
        }
    }
    

    示例2:对负数进行左移

    public class Main {
        public static void main(String[] args) {
            int i = -5; // 二进制(补码):11111111 11111111 11111111 11111011
            int j = 2;
    
            i <<= j; // 等价于 i = i << j
            // 左移2位:11111111 11111111 11111111 11101100 (-20)
    
            System.out.println(i); // 输出:-20
        }
    }
    

    示例3:可能的溢出问题

    public class Main {
        public static void main(String[] args) {
            int i = 1073741824; // 二进制:01000000 00000000 00000000 00000000
            int j = 1;
    
            i <<= j; // 左移1位:10000000 00000000 00000000 00000000
            // 超过32位,结果变为负数(溢出)
            
            System.out.println(i); // 输出:-2147483648
        }
    }
    

    注意点

    1. 左移等价于乘以2的幂

    2. 每向左移1位,相当于乘以2
    3. 例如:5 <<= 1 等价于 5 * 2 = 105 <<= 2 等价于 5 * 4 = 20
    4. 注意,左移不会检查溢出问题,可能导致负数或错误的结果。
    5. 溢出问题

    6. 移位可能会导致高位被截断,特别是当操作数接近数据类型的最大值时。
    7. 适用数据类型

    8. 左移操作支持整型和长整型(intlong)。
    9. 如果操作的类型小于 int(比如 byteshort),会被提升为 int 再执行移位运算。

    作者:凭君语未可

    物联沃分享整理
    物联沃-IOTWORD物联网 » 一篇文章让你学会Java之左移、右移操作

    发表回复