Java基础语法(五)—位运算符

时间:2023-02-15 16:26:09

5.位运算符

题外话:我们都知道,在计算机中,参与计算的都是二进制数据,而二进制数据又分为原码、反码、补码,运算的时候都是用补码来运算。

(1)<<:将参与运算的二进制数据向 左 移动,在低位产生的空位用 0 来补齐。

注意:在java中,整数的默认类型为 int 型,也就是32位,而为了在下文中叙述方便,我就使用8位的byte型了。

class Demo1{    
public static void main(String[] args){

byte a = 7;
// 把a变量的二进制的值左移2位
System.out.println(a << 2); // 输出结果:28
}
}
整数 7 的二进制形式: 0 0 0 0 0 1 1 1
整数 7 的二进制左移两位: 0 0 0 1 1 1 0 0
———-
class Demo1{    
public static void main(String[] args){

byte a = -7;
// 把a变量的二进制的值左移2位
System.out.println(a << 2); // 输出结果:-28
}
}
-7 原码: 1 0 0 0 0 1 1 1
    反码: 1 1 1 1 1 0 0 0
    补码: 1 1 1 1 1 0 0 1
    补码:(左移之后) 1 1 1 0 0 1 0 0
    反码: 1 1 1 0 0 0 1 1
    原码: 1 0 0 1 1 1 0 0

      在这里需要简单解释一下,因为计算机的运算都是以补码的形式进行,而最高位的 0 或 1 代表的是符号位正或负,(以前不清楚这一点,正数的时候还好,一旦遭遇负数,脑子一团浆糊)。那么我们十进制的-7在进行移位运算之前,需要先转换成补码形式,然后才可以移位,(不要觉得我们进行到这里就结束了哈)实际上我们在控制台输出的还是 十进制的数,所以还要将移位之后的补码再转换成原码才行。
      原码、反码、补码之间的转换我在之前的《java基础语法(二)》中就有过介绍,在这里我再说明一下吧:
      正数:原码=反码=补码
      负数:原码变反码:最高位符号位不变,其他数值位 0变1、1变0。
                反码变补码:反码加1即可得。


(2)>>:(带符号右移)将参与运算的二进制数据向右移动,在高位产生的空位:如果高位是0,就用0补齐;如果高位是1,就用1补齐。

class Demo1{    
public static void main(String[] args){

byte a = 7;
// 把a变量的二进制的值右移2位
System.out.println(a >> 2); // 输出结果:1
}
}
整数 7 的二进制形式: 0 0 0 0 0 1 1 1
整数 7 的二进制右移两位: 0 0 0 0 0 0 0 1
———-
class Demo1{    
public static void main(String[] args){

byte a = -7;
// 把a变量的二进制的值右移2位
System.out.println(a >> 2); // 输出结果:-2

}
}
-7 原码: 1 0 0 0 0 1 1 1
    反码: 1 1 1 1 1 0 0 0
    补码: 1 1 1 1 1 0 0 1
    补码:(右移之后) 1 1 1 1 1 1 1 0
    反码: 1 1 1 1 1 1 0 1
    原码: 1 0 0 0 0 0 1 0

负数的带符号右移运算的原理同左移原理相同,这里就不赘述了。


(3)>>>:(无符号右移)将参与运算的二进制数据向右移动,在高位所产生的空位用 0 补齐。

class Demo1{    
public static void main(String[] args){

byte a = 7;
System.out.println(a >>> 2); // 输出结果:1
}
}

正数的无符号右移和正数的带符号右移的结果相同。所以相对来说,正数的无符号右移其实没有啥太大的意义。

class Demo1{    
public static void main(String[] args){

int a = -7;
System.out.println(a >>> 2); // 输出结果:1073741822

}
}
-7原码: 1000 0000 0000 0000 0000 0000 0000 0111
    反码: 1111 1111 1111 1111 1111 1111 1111 1000
    补码: 1111 1111 1111 1111 1111 1111 1111 1001
    补码:(右移之后) 0011 1111 1111 1111 1111 1111 1111 1110

注意:无符号右移只是对32位和64位的值有意义。上图中,右移后的补码最高符号位为0,所以为正数,所以原码就是它本身,那么转换成十进制之后的值为:1073741822