java中的位运算

embedded/2024/9/24 15:37:01/

位运算是对整数的二进制位进行操作的一种运算。在java中long, int, short, char和byte类型都可以使用位运算。

位运算的过程如下:首先将十进制整数转换成二进制表示形式,然后将位运算符应用于每个二进制数位,并计算结果。最后,将二进制结果转换回其十进制表示。

位运算符有以下几种:与运算(&)、或运算(|)、异或运算(^)、取反运算(~)、左移(<<)、右移(>>)等。下面来分别看下每个运算。

移位运算

移位运算有三种

左移(<<):将二进制位向左移动指定的位数,右侧用0填充。

java">        int a = 5;//二进制101a = a << 1;//左移一位,右补0 = 1010,换算成10进制变成10System.out.println(a);

右移(>>):将二进制位向右移动指定的位数,保持符号位。

java">        int b = 8;//二进制 100b = b >> 1;//右移一位,变成 10 转成十进制=4System.out.println(b);

无符号右移(>>>):将二进制位向右移动指定的位数,左侧用0填充,不考虑符号位。

我们知道对于有符号整数,第一位为符号位。正数符号位为0,负数的符号位为1。这里无符号右移左侧补0会将负数变成一个正数。原来是正数的数无符号右移和普通的右移没有区别。

java">int a = -8; // 二进制: 1111...1000
int result = a >>> 1; // 结果: 2147483644 (0111...1100)

移位运算整体还是比较好理解,左移相当于将数字乘以2的移位数次方。右移相当于将数字除以2的移位数次方,向下取整。

与运算(&)

它对两个整数的二进制位进行操作,只有在两个对应的二进制位都为1时,结果才为1;否则结果为0。

假设有两个整数 ab

  • a = 5(二进制表示为 0101
  • b = 3(二进制表示为 0011

进行与运算:

  0101  (5)
& 0011  (3)
--------0001  (1)

通过与运算提取特定的位。也可以用来判断某些标志位是否被设置。

判断奇偶

java">isOdd(int a){return  1 == (a&1);
}

将要判断的数与1进行取与操作,只要结果为1则判断当前数为奇数。因为如果结果为1,则证明当前数二进制最后一位为1,是个奇数。

权限控制

权限控制这里可以结合linux文件系统的三个权限,rwx 即 读(1),写(2),执行(4)。

linux 可以使用chmod 来给用户赋予权限 ,7代表所有权限,5代表读和执行权限,大致可以根据以下与运算来判断是否有某个权限:

java">int READ = 1;   // 0001
int WRITE = 2;  // 0010
int EXECUTE = 4; // 0100int userPermissions = 5; // 0101 (具有读和执行权限)boolean canRead = (userPermissions & READ) != 0; // 检查读权限
boolean canWrite = (userPermissions & WRITE) != 0; // 检查写权限System.out.println("Can read: " + canRead); // 输出: Can read: true
System.out.println("Can write: " + canWrite); // 输出: Can write: false

清零特定位

如数字15(1111),要将其第二位清理,只需15 & (1011=11)即可。

掩码计算

计算机网络中,有子网掩码,子网掩码 & IP地址就可以计算处当前计算机所处的网络。

例如局域网中,通常子网掩码255.255.255.0,假设某个IP地址为192.168.10.111则将两者进行与运算后结果为192.168.10.0为当前ip所处的网络。

255的二进制是 11111111与任何一个8位以内的整数进行与运算都等于该数的本身。

相反0的二进制是0,与任何一个8位以内的二进制整数进行与运算结果都是0。

或运算(|)

或运算对两个二进制数的每一位进行比较,只要有一个位为 1,结果位就为 1;如果两个位都为 0,结果位为 0。

java">        int a = 10; // 二进制: 1010int b = 12; // 二进制: 1100int result = a | b; // 结果: 1110 (十进制: 14)System.out.println(result); // 输出: 14

或运算可以用来进行一些状态标识。在游戏开发中,可以使用或运算来表示角色的状态。例如,角色可以同时处于多个状态,如“跳跃”、“攻击”等。

JUMPING = 1   # 0001
ATTACKING = 2 # 0010
DEFENDING = 4 # 0100# 角色当前状态为跳跃和攻击
character_state = JUMPING | ATTACKING  # 结果: 0011# 检查角色是否在攻击
is_attacking = character_state & ATTACKING != 0  # 结果为 True
异或运算(^)

异或运算当两个对应的二进制位不相同,结果为1;相同则为0。

  • 0^0 = 0
  • 0 ^ 1 = 1
  • 1^ 0 = 1
  • 1 ^ 1 = 0
java">        int a = 10; // 二进制: 1010int b = 12; // 二进制: 1100int result = a ^ b; // 结果: 0110 (十进制: 6)System.out.println(result); // 输出: 6

异或运算有以下特点:

a^a = 0 :一个数与自己进行异或结果为0。

a^0=a : 以数与0进行异或操作结果为其本身。

abb=a:对一个值进行两次异或运算使用同一个数,可以恢复到原始值。这使得异或运算在加密和解密中非常有用。因为这样运算是可逆的。

异或运算与运算的顺序无关,abb=a 等价于 a(bb) = a ^0=a

使用异或运算进行两个数值交换

java">        int a = 5;int b = 3;a = a^b;b = a^b; //a = a^b 代入 b = a^b^b = a 现在b=a = 3a = a^b; //此时b=a ,a= a^b 带入 a^b^a = bSystem.out.println(a+" "+b);

找出数组中只出现一次的元素

java">        int[] arr = {5,2,3,2,4,5,4};int result = 0;for (int i : arr) {result ^= i;}System.out.println(result);

这里使用了异或运算的对一个值进行两次相同异或运算等于同一个数

取反运算(~)

取反运算将每个二进制位取反,0变成1,1变成0。

java">        int a = 8;//0000 1000/**取反后 1111 01111111 0111 是负数的补码表示形式,要得到其对应的十进制数,我们需要将其转换为正数。负数的补码是将其绝对值的二进制表示取反后加 1,所有最后结果是-9*/System.out.println(~a);

位运算总结下如下表格:

A	B	A|B	A&B	A^B	~A
0	0	0	0	0	1
1	0	1	0	1	0
0	1	1	0	1	1
1	1	1	1	0	0

http://www.ppmy.cn/embedded/116146.html

相关文章

SpringBoot | Maven快速上手

文章目录 一、Maven1.1 Maven 简介&#xff1a;1.2 Maven 的核心功能&#xff1a;1.2.1 项目构建&#xff1a;1.2.2 依赖管理&#xff1a; 1.3 Maven 仓库&#xff1a;1.3.1 本地仓库&#xff1a;1.3.2 中央仓库&#xff1a;1.3.3 私服&#xff1a; 二、第一个 SpringBoot 程序…

揭开数据能力的神秘面纱

在当今数字化时代&#xff0c;数据已成为企业和组织的重要资产。拥有强大的数据能力&#xff0c;能够帮助企业更好地理解市场、客户和业务&#xff0c;从而做出更明智的决策。然而&#xff0c;数据能力究竟是什么&#xff1f;它包含哪些方面&#xff1f;又如何提升呢&#xff1…

Knife4j 一款基于Swagger的开源文档管理工具

一、简单介绍 1.1 简介 Knife4j 是一款基于Swagger的开源文档管理工具&#xff0c;主要用于生成和管理 API 文档 二、使用步骤&#xff1a; 2.1 添加依赖&#xff1a; <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spr…

react hooks--useReducer

概述 很多人看到useReducer的第一反应应该是redux的某个替代品&#xff0c;其实并不是 ◼ useReducer仅仅是useState的一种替代方案&#xff1a;  在某些场景下&#xff0c;如果state的处理逻辑比较复杂&#xff0c;我们可以通过useReducer来对其进行拆分&#xff1b; 或…

SSL 最长签发时间是多久?

在当今数字化的时代&#xff0c;网络安全变得至关重要。为了确保数据在网络传输中的安全性&#xff0c;SSL&#xff08;Secure Sockets Layer&#xff0c;安全套接层&#xff09;证书被广泛应用。那么&#xff0c;SSL最长签发时间是多久呢&#xff1f; SSL证书是一种数字证书&…

华为HarmonyOS灵活高效的消息推送服务(Push Kit) -- 7 推送卡片刷新消息

场景介绍 如今衣食住行娱乐影音应用占据了大多数人的手机&#xff0c;一部手机可以满足日常大多需求&#xff0c;但对需要经常查看或进行简单操作的应用来说&#xff0c;总需要用户点开应用体验较繁琐。针对此种场景&#xff0c;HarmonyOS提供了Form Kit&#xff08;卡片开发服…

工业交换机故障快速排查的方法有哪些

在现代工业自动化的环境中&#xff0c;工业交换机作为网络连接的重要设备&#xff0c;其稳定性和可靠性至关重要。然而&#xff0c;实际使用过程中难免会遇到各种故障&#xff0c;这对生产线和系统的正常运作造成了影响。为了有效应对这些问题&#xff0c;下面将介绍一些工业交…

深度学习速通系列:在进行大模型微调时,如何确定最佳的学习率和批次大小?

在进行大模型微调时&#xff0c;确定最佳的学习率和批次大小&#xff08;batch size&#xff09;通常需要考虑以下几个方面&#xff1a; 数据集的大小和特性&#xff1a;数据集的大小直接影响批次大小的选择。较大的数据集可能允许使用较大的批次大小&#xff0c;而较小的数据集…