Java移位运算符

    Java中移位运算符有三种,分别是左移(<<)、有符号右移(>>)和无符号右移(>>>),移位运算符主要是对数据的二进制位进行操作的,由于计算机中对数字是按补码形式存储的,所以在对数字进行位运算时,也就是对数字的补码进行操作,而不是原码和反码(建议不了解原码、反码和补码的先看一下https://blog.csdn.net/lanmuhhh2015/article/details/78549400)。
1、左移运算符(<<)
左移就是将数字的补码的所有位向左移,低位补0。假设数字num左移3位,则移位后的结果为num*2^3,测试代码如下:

/*
 * 补码:0000 1010 (移位前 10)
 * 补码:0101 0000 (移位后 80)
 * */
System.out.println(10<<3); // 结果为80
/*
 * 补码:1111 0110 (移位前 -10)
 * 补码:1011 0000 (移位后 -80)
 * */
System.out.println(-10<<3); // 结果为-80

// 移的位过大时,会导致溢出,结果就不正确了,所以移位时要考虑溢出的情况
System.out.println(10<<29); //1073741824
System.out.println(10<<28); //-1610612736
System.out.println(-10<<29); //-1073741824
System.out.println(-10<<28); //1610612736

2、有符号右移运算符(>>)
有符合右移运算符就是将所有位向右移,高位补符号位,如果是正数则补0,负数补1。右移就是将数字相除,每移一位就将目标数字除2,测试代码如下:

/*
 * 0000 1010 (移位前 10)
 * 0000 0010 (移位后 2)
 * */
System.out.println(10>>2); // 结果为2
/*
 * 1111 0110 (移位前 -10)
 * 1111 1101 (移位后 2)
 * */
System.out.println(-10>>2); // 结果为-3

// 有符号右移位数过大时正数不存在溢出,因为是数值变小呢,但负数会有问题,因为移到最后补码全部为1了,此时的原码值为-1
System.out.println(10>>29); //0
System.out.println(-10>>29); //-1

3、无符号右移运算符(>>>)
无符号右移就是所有位向右移,不管正数还是负数,高位都补0。测试代码如下:

/*
 * 0000 1010 (移位前 10)
 * 0000 0010 (移位后 2)
 * */
System.out.println(10>>>2); // 结果为2
/*
 * 补码:1111 1111 1111 1111 1111 1111 1111 0110 (移位前 -10)
 * 补码:0011 1111 1111 1111 1111 1111 1111 1101 (移位后 1073741821)
 * */
System.out.println(-10>>>2); // 结果为1073741821

// 无符号右移对于正数没问题,但对于负数,无符号右移得出的结果是错误的,所以不要对负数进行无符号右移操作
System.out.println(10>>>29); //0
System.out.println(-10>>>29); //7

总结:
    在移位时要注意,左移时不管正数或负数,都得考虑移位太大时的溢出问题;对于有符号右移操作,需要考虑负数右移时的结果,可能和想的会有区别;对于无符号右移操作,正数时没有问题的,但负数时错误的,所以不要对负数进行无符号右移操作。

你可能感兴趣的:(Java语言)