java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java特殊运算符

Java中特殊运算符及其应用详解

作者:是江迪呀

当涉及位操作和位级运算时,Java 提供了一组特殊的运算符,即左移(<<)和右移(>>)运算符,下面小编就带大家深入了解一下它们的具体应用吧

一、前言

当涉及位操作和位级运算时,Java 提供了一组特殊的运算符,即左移(<<)和右移(>>)运算符。这些运算符与普通的算术和逻辑运算符不同,它们操作的是数字的二进制位。位操作是计算机底层编程中常用的技巧,能够高效地执行一些操作,如数值乘除以2的幂次方,处理标志位,以及在一些位级编码场景下进行数据处理。

左移和右移运算符用于将二进制位向左或向右移动指定的位数,从而实现对数值的快速操作。左移操作将数值的二进制表示向左移动,等效于乘以2的幂次方,而右移操作将数值的二进制表示向右移动,等效于除以2的幂次方。这些运算符在处理大数据集、位掩码、网络协议以及嵌入式系统等领域都具有广泛的应用。

然而,需要注意的是,位操作并不常见于一般的业务逻辑编程,而更多地出现在需要对二进制数据进行处理的底层系统级编程中。在使用位操作时,应该清晰地理解位操作的语义,防止出现意外错误。同时,要考虑到可读性和代码维护性,不应滥用位操作,而是在合适的场景下使用,以提高代码的效率和性能。

二、Java的左移、右移运算符

记忆技巧: 尖括号的方向朝向哪就是哪移。

左移就是将目标转换为二进制后,从右向左移动一位,右边补零,左边移除。

右移就是将目标转换为二进制后,从左向右移动一位,左边补零,右边移除。。

三、Java中左移、右移使用场景

可以代替乘(左移)和除(右移),如下:

package zd.hjd.test.synchronizedtest;
public class MyTestMain {
    public static void main(String[] args) {
        System.out.println(4*2);
        System.out.println(4<<1);
        System.out.println(4/2);
        System.out.println(4>>1);
    }
}

输出结果:

8
8
2
2

四、使用左移、右移优点和弊端

4.1 优点

使用左移(<<)和右移(>>)的好处在于它们可以在某些情况下提供更高效的数值操作,特别是涉及到2的幂次方的操作。以下是一些使用左移右移的好处:

4.2 弊端

五、使用左移、右移注意事项

1.带符号左移需要考虑移动后数字变为负数的情况,因为二进制的首位为符号位。

2.从上述中我们知道,左移就是将一个数字的二进制编码向左边移动,右边补零,右移相反。如果一个int类型的数字向左移32位结果是不是就是0呢?答案是错误的。当int类型数字进行左移,并且左移位数大于等于32位时,会先与32求余,然再进行移动。32%32 = 0,使用int类型向左移32位相当于不移动,byteshort类型同理。long类型是64位。

public class MoveLeft {
    public static void main(String[] args) {
       int a = 10;
        byte b = 50;
        short s = 60;
        System.out.println(a >> 1);// 5
        System.out.println(a << 1);// 20
        System.out.println(a << 32);// 10
        System.out.println(a << 33);// 20
        System.out.println(b << 32);// 50
        System.out.println(b << 33);// 100
        System.out.println(s << 32);// 60
        System.out.println(s << 33);// 120
        long longValue = 733183670L;
        System.out.println("longValue:" + (longValue));//打印longValue
        System.out.println("longValue左移1位:" + (longValue << 1));//左移1位
        System.out.println("longValue左移8位:" + (longValue << 8));//左移8位
        //当long类型左移位数大于等于64位操作时,会先求余后再进行移位操作
        System.out.println("longValue左移64位:" + (longValue << 64));//求余为64%64=0,相当于左移0位(不移位)
        System.out.println("longValue左移72位:" + (longValue << 72));//求余为72%64=8,相当于左移8位
        System.out.println("longValue左移128位:" + (longValue << 128));//求余为128%64=0,相当于左移0位(不移位)
    }
}

3.double和float不能使用位移来操作,编译不通过。

六、无符号右移>>>

无符号右移和右移原理一样,只不过是右移后在左边补零后舍弃掉符号位。如下所示:

public class MoveLeft {
    public static void main(String[] args) {
        int a = -10;
        System.out.println(a >>> 1);// 结果是 2147483643
    }
}

执行的过程如下:

//向得出-10的二进制,需要得到10的二进制
0000 0000 0000 0000 0000 0000 0000 ‭‭1010‬‬// 10 二进制如下
1111 1111 1111 1111 1111 1111 1111 0101// 10 的反码
1111 1111 1111 1111 1111 1111 1111 0110 //反码+1 就为 -10 的二进制
0111 1111 1111 1111 1111 1111 1111 1011// 右移一位
//转换为10进制 为 2147483643

记住Java中没有无符号左移。因为左移操作符 << 总是保持符号位,即使在移动过程中可能会导致符号位变为1。如果需要进行无符号左移操作,可以使用无符号右移操作 >>> 来实现。因为在大多数情况下,无符号左移和无符号右移的效果是一样的,都是向左或向右移动指定位数,只是填充的位不同。

七、Java中的其它特殊运算符

7.1 &

按位与运算 &是双目运算符。其功能是参与运算的两数各对应的二进制位相与。只有对应的两个二进位均为1时,结果位才为1 ,否则为0。参与运算的数以补码方式出现。

使用场景:

例如,如果有一个整数 a 表示某个权限的掩码,另一个整数 b 表示用户的权限,通过 a & b 运算可以判断用户是否具有某个权限。

7.2 |

按位或运算 |是双目运算符。其功能是参与运算的两数各对应的二进制位相或。只要两数的二进制位中有一个是1,那么按位或的结果就是1;只有二进制两位都为0时,结果为0。

使用场景:

例如,如果有一个整数 a 表示某个权限的掩码,另一个整数 b 表示用户的权限,通过 a | b 运算可以将用户的权限添加到掩码中。

7.3 ^

按位异或运算 ~是双目运算符。其功能是参与运算的两数各对应的二进制位相异或。两个数字的二进制位相同则取0,不同值则取1。

异或运算符具有以下的性质:

(1)交换律: (2)结合律:

(a^b)^c == a^(b^c)

(3)对于任何数X,都有:

x^x=0,x^0=x

(4)自反性

A XOR B XOR B = A xor 0 = A

使用场景:

异或运算最常见于多项式除法,不过它最重要的性质还是自反性A XOR B XOR B = A,即对给定的数A,用同样的运算因子(B)作两次异或运算后仍得到A本身。这是一个神奇的性质,利用这个性质,可以获得许多有趣的应用。

例如,大部分程序教科书都会向初学者指出,要交换两个变量的值,必须要引入一个中间变量。但如果使用异或,就可以节约一个变量的存储空间: 设有A,B两个变量,存储的值分别为a,b,则以下三行表达式将互换他们的值 表达式 (值) :

A=A XOR B (a XOR b) 
B=B XOR A (b XOR a XOR b = a)
A=A XOR B (a XOR b XOR a = b)

public class MyTestMain {
    public static void main(String[] args) {
        int a = 5;
        int b = 6;
        a = a^b;
        b = a^b;
        a = a^b;
        System.out.println("a:" + a);
        System.out.println("b:" + b);
    }
}

输出结果:

a:6
b:5

google的一个面试题:

一个数组存放若干整数,一个数出现奇数次,其余数均出现偶数次,找出这个出现奇数次的数?

上面的问题可以使用按位异或运算巧妙解决:

public class MyTestMain {
    public static void main(String[] args) {
        int[] nums = {2, 2, 3, 3, 4, 4, 5};
        int returnValue = 0;
        for (int num : nums) {
            returnValue ^= num;
        }
        System.out.println(returnValue);
    }
}

输出结果:

5

以上就是Java中特殊运算符及其应用详解的详细内容,更多关于Java特殊运算符的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文