Java - 位运算的基本原理和用途

本文详细介绍了Java中的位运算,包括按位与(&),按位或(|),按位异或(^),取反(~),左移(<<),右移(>>),以及无符号右移(>>>)。文中还展示了这些运算在判断奇偶性、交换数值、幂运算、判断2的幂次方和加解密中的实际应用。
摘要由CSDN通过智能技术生成

前言

Java 当中的位运算有很多种,它们都是针对二进制位进行操作。包括:

  • 按位与:&
  • 按位或: |
  • 按位异或: ^
  • 取反:~
  • 左移位、右移位运算符:<< ,>> ,>>>

接下来我们就复习一下相关的运算知识。

一. Java 位运算基本操作

1.1 按位与 &

按位与:两个二进制数对应位上的数字都为1时,结果位上的数字才为1。否则结果位上的数字为0。按位与通常用于掩码操作或清零操作。

举例如下:

3的二进制表示为:0 0 1 1
5的二进制表示为:0 1 0 1
那么3 & 5 则表示为:
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
最终结果为:
0011 & 0101 = 0001 = 1

按位与 常见的运用有:

  • 判断一个数是否为奇数n & 1 ==1 代替 (n % 2 == 1)
  • 清除一个数的二进制末尾 n 位:x & (~0 << n)

1.2 按位或 |

按位或:二进制数对应位上的数字有一个为1时,结果位上的数字就为1

举例如下:

3的二进制表示为:0 0 1 1
5的二进制表示为:0 1 0 1
那么3 | 5 则表示为:
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
最终结果为:
0011 | 0101 = 0111 = 7

按位或 常用的运用有:

  • 将一个数的二进制末n位设置为1:x | ((1 << n) - 1)

1.3 按位异或 ^

按位异或:两个二进制数对应位上的数字不相同时,结果位上的数字为1;否则结果位上的数字为0。

举例如下:

3的二进制表示为:0 0 1 1
5的二进制表示为:0 1 0 1
那么3 ^ 5 则表示为:
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
最终结果为:
0011 | 0101 = 0110 = 6

按位异或 常见的运用有:

  • 加解密操作。

还有常见的运算公式:

  • x ^ 0 = x​
  • x ^ 1 = ~x

1.4 按位取反 ~

按位取反:是指一个二进制数的每个位取反,即0变成1,1变成0。说简单点,对于一个二进制数,取反后的值也就是数值加1后取反数 : ~n = (n+1) * -1

举例如下:

3的二进制表示为:0000 0000 0000 0000 0000 0000 0000 0011
按位取反操作会将每一位取反,即将0变为1,将1变为0。所以,对3进行按位取反的结果为:
1111 1111 1111 1111 1111 1111 1111 1100
这个二进制数表示的是一个负数,根据补码的规则,我们需要将其转换为原码来得到对应的十进制数。转换原码的方法是将补码的每一位取反,然后再加1
对于
1111 1111 1111 1111 1111 1111 1111 1100
取反得到
0000 0000 0000 0000 0000 0000 0000 0011
再加1得到
0000 0000 0000 0000 0000 0000 0000 0100,
即十进制数-4

1.5 位移运算

位移运算分为:

  • 左移运算符(<<
  • 右移运算符(>>
  • 无符号右移运算符(>>>

注意:没有 <<< 这种运算符的哦~

1.5.1 左移运算符 <<

左移运算符:将操作数的二进制表示向左移动指定的位数,右侧用0填充。例如,a << b表示将a的二进制表示向左移动b位。

举例如下:

3 << 2 = 12
3 的二进制表示为 0011
3 << 2 的运算过程如下:
0011 -> 1100
因此,3 << 2 = 12

说白了就是这个数乘以2的几次幂。

1.5.2 右移运算符 >>

右移运算符 :将操作数的二进制表示向右移动指定的位数,左侧用符号位(即正负号位)填充。例如,a >> b表示将a的二进制表示向右移动b位。

举例如下:

-6 >> 1 = -3
-6 的二进制表示为
1111 1111 1111 1111 1111 1111 1111 1010
-6 >> 1 的运算过程如下:(关注后面的1010 --> 1101),101 整体向右移动了一位,左侧由1填充。
1111 1111 1111 1111 1111 1111 1111 1101
因此,-6 >> 1 = -3

说白了就是这个数除以2的几次幂。 (取整)

  • 如果操作数是负数:右移操作会在左侧用1填充。
  • 如果操作数是正数,右移操作会在左侧用0填充

1.5.3 无符号右移运算符 >>>

无符号右移运算符 :将操作数的二进制表示向右移动指定的位数,左侧用0填充。无符号右移运算符不考虑符号位,所以无论操作数是正数还是负数,都会将左侧的位数填充为0。例如,a >>> b表示将a的二进制表示向右移动b位。

和右移运算符的区别就是:

  • 无论是正数还是负数:右移操作会在左侧都用0填充。

例如:6 >>> 1 = 6 / 2¹ = 3

二. 位运算实际运用

2.1 判断奇偶性(&的运用)

一个数和1做按位与操作,返回结果是1代表奇数,否则偶数。

n & 1 == 1

2.2 交换两个数的值(^的运用)

将两个数字异或比较3次即可。

public static void main(String[] args) {
    int a = 3, b = -7;
    System.out.println("a= " + a + ",b= " + b);
    a ^= b;
    b ^= a;
    a ^= b;
    System.out.println("a= " + a + ",b= " + b);
}

结果如下:
在这里插入图片描述

2.3 2的幂运算(<< 的运用)

给定一个数,想要乘以2的几次m幂:例如3 * 2 的六次幂 = 192,可表示为:

3 << 6

2.4 判断一个数是否是2的幂次方(&的运用)

对于一个正整数 n,如果它是 2 的幂次方,则有 n & (n - 1) == 0

2.5 加解密操作(^的运用)

private static final String TOKEN = "as21312b&*@#";

public static String encrypt(String str) {
    char[] chars1 = str.toCharArray();
    char[] chars2 = TOKEN.toCharArray();
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < chars1.length; i++) {
        builder.append((char) (chars1[i] ^ chars2[i % chars2.length]));
    }
    return builder.toString();
}

public static String decrypt(String str) {
    return encrypt(str);
}

public static void main(String[] args) {
    String str = "Hello World";
    // 加密
    String encrypt = encrypt(str);
    System.out.println(encrypt);
    // 解密
    System.out.println(decrypt(encrypt));
}

运行结果如下:
在这里插入图片描述
上面是一个简单的案例,你也可以在他的基础上,多加一层判断,比如:

  • 防止二次加密。
  • 没有加密的字符串经过解密后还是原字符串。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zong_0915

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值