按位操作符与移位操作符原理

  • A+
所属分类:编程茶楼


共计 3006 个字符,预计需要花费 8 分钟才能阅读完成。

按位操作符用来操作整数基本类型中的单个“比特”(bit),即二进制位,会对两个参数中对应的位执行布尔代数运算,并最终生成一个结果。
按位操作符来源于C语言面向底层的操作,在这种操作中经常需要直接操纵硬件,设置硬件寄存器内的二进制位,不过,当下Java开发过程中并不会过多的用到位运算,可供了解。
两个输入位都是1,则按位‘与’操作符(&)生成一个输出位1,否则生成一个输出位0;
两个输入位只要有一个是1,则按位‘或’操作符(|)生成一个输出位1,只有两个输入位都是0,才会生成一个输出位0;
两个输入位都是0或者1,则按位‘异或’操作符(^)生成一个输出位0,当两个输入位不一致时,才会生成一个输出位1;
按位‘非’操作符(~)生成与输入位相反的值--即输入0,输出1;输入1,输出0;

按位‘非’操作符,也称取反操作符,属于一元操作符,只能对一个操作数进行操作(其他按位操作符是二元操作符)。

tips:由于‘~’是一元操作符,所以不可与‘=’联合使用

可执行按位‘与’、按位‘或’和按位‘异或’运算,但是不能执行按位‘非’(Java编程思想中提及:大概是为了避免与逻辑NOT混淆)
/**
 * @author plm
 * @create 2021/1/3 23:00
 */
public class BitwiseOperators {
    public static void main(String[] args) {
        int i = 666;
        System.out.println(Integer.toBinaryString(i));
        int j = 777;
        System.out.println(Integer.toBinaryString(j));

        System.out.println("===========按位运算符=============");
        // 按位与  &
        System.out.println("按位与&   :" + Integer.toBinaryString(i & j));
        // 按位或  |
        System.out.println("按位与|   :" + Integer.toBinaryString(i | j));
        // 按位异或  ^
        System.out.println("按位与^   :" + Integer.toBinaryString(i ^ j));
        System.out.println("===========按位运算符=============");
    }
}

/*
1010011010
1100001001
===========按位运算符=============
按位与&   :1000001000
按位与|   :1110011011
按位与^   :110010011
===========按位运算符=============
*/
移位操作符操作的运算对象也是二进制的“位”,并且只可以用来处理整数类型(基本类型的一种)。
左移位操作符(<<)能按照操作符右侧指定的位数将操作符左侧的操作数向左移动(在低位补0);
“有符号”右移位操作符(>>)则按照操作符右侧指定的位数将操作符左边的操作数向右移动,此时操作符使用“符号扩展”:如符号为正,则在高位插入0;如符号为负,则在高位插入1。
Java中增加了“无符号”右移位操作符(>>>),该操作符使用“零扩展”:无论正负,都在高位插入0。--此操作符在C或者C++中没有的
对char、byte和short类型的数值进行移位时,移位之前会先被转换成int类型,并且得到的结果也是int类型的值;(只有数值右端的低5位才有用,这样可以防止我们移位超过int类型所具有的位数--因为2的5次方位32,而int型值只有32位)
对long类型的数值进行移位处理,最后得到的结果也是long。(只有数值右端的低6位才有用,这样可以防止我们移位超过long类型所具有的位数)

tips:但是在“>>>=”使用过程中,如果是对byte和short值进行这样的移位运算,得到的可能不是正确的结果,他们会先被转成int型,再进行右移操作,然后被截断,赋值给原来的类型,在这种情况下可能得到-1的结果。

/**
 * @author plm
 * @create 2021/1/3 23:47
 */
public class ShiftOperators {
    public static void main(String[] args) {
        int i = -1;
        System.out.println("int i 移位运算符 :" + Integer.toBinaryString(i));
        i >>>= 10;
        System.out.println("int i 移位运算符 :" + Integer.toBinaryString(i));

        System.out.println("=============================");

        long j = -1;
        System.out.println("long j 移位运算符 :" + Long.toBinaryString(j));
        j >>>= 10;
        System.out.println("long j 移位运算符 :" + Long.toBinaryString(j));

        System.out.println("=============================");

        short s = -1;
        System.out.println("short s 移位运算符 :" + Integer.toBinaryString(s));
        s >>>= 10;
        System.out.println("short s 移位运算符 :" + Integer.toBinaryString(s));

        System.out.println("=============================");

        byte b = -1;
        System.out.println("byte b 移位运算符 :" + Integer.toBinaryString(b));
        b >>>= 10;
        System.out.println("byte b 移位运算符 :" + Integer.toBinaryString(b));
    }
}

/*
int i 移位运算符 :11111111111111111111111111111111
int i 移位运算符 :1111111111111111111111
=============================
long j 移位运算符 :1111111111111111111111111111111111111111111111111111111111111111
long j 移位运算符 :111111111111111111111111111111111111111111111111111111
=============================
short s 移位运算符 :11111111111111111111111111111111
short s 移位运算符 :11111111111111111111111111111111
=============================
byte b 移位运算符 :11111111111111111111111111111111
byte b 移位运算符 :11111111111111111111111111111111
*/
  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: