Java位运算及移位运算

java中能表示整数数据类型的有byteshortcharintlong,在计算机中占用的空间使用字节描述,1个字节使用8位二进制表示。

数据类型字节数二进制位数表示范围默认值
byte18-27 – 27-10
char2160 – 216-1'\u0000' (代表字符为空 转成int就是0)
short216-215 – 215-10
int432-231 – 231-10
long864-263 – 263-10L

1. 原码、反码、补码

使用位运算前需要先弄清楚这几个概念

1.1. 原码

原码也叫机器码,整数的二进制形式表示,最高位为符号位。1表示负数,0表示正数,除去符号位后剩余其他的所有位是该整数的绝对值的二进制值。

int a = 7; //原码二进制表示为:00000000 00000000 00000000 00000111
int b = -7;//原码二进制表示为:10000000 00000000 00000000 00000111

1.2. 反码

反码需要区分是正数还是负数,正数的反码跟原码相同,负数的反码是除符号位外,其他位取反(即负数的最高位是1不变,其他位0变成1,1变成0)。

int a = 7; //反码二进制表示为:00000000 00000000 00000000 00000111
int b = -7;//反码二进制表示为:11111111 11111111 11111111 11111000

1.3. 补码

补码也需要区分是正数还是负数,正数的补码跟原码相同,负数的补码是反码最低位加1。

int a = 7; //补码二进制表示为:00000000 00000000 00000000 00000111
int b = -7;//补码二进制表示为:11111111 11111111 11111111 11111001

说完了概念,其实这里的原码是方便给人看的,对于计算机运算来说都是使用补码形式操作。以下的位运算和移位运算都是基于补码进行的。

2. 位运算

2.1. 位运算术语解释

位运算符含义解释备注
&按位与两个整数按位对齐,当对齐的两位同时为1则结果为1,否则为0
``按位或两个整数按位对齐,当对齐的两位只要有一个为1则结果为1,否则为0
~按位非只能适用于一个整数的自身操作,按位取反,即1变成0,0变成1单目运算符
^按位异或两个整数按位对齐,当对齐的两位相同时为0,否则为1

2.2. 位运算示例

我们以上面的int a = 7int b = -7举例位运算的操作。
a的补码二进制为:00000000 00000000 00000000 00000111
b的补码二进制为:11111111 11111111 11111111 11111001
1、a&b

按位与的结果补码为:00000000 00000000 00000000 00000001
因为最高位为0,所以为正数,`正数的原码反码补码都相同`,所以原码也为:
00000000 00000000 00000000 00000001
转换成十进制的结果就是1

2、a|b

按位或的结果补码为:11111111 11111111 11111111 11111111
最高位为1,所以是负数。
反码=补码-1,得到反码:11111111 11111111 11111111 11111110
原码=反码除符号位取反,得到原码:10000000 00000000 00000000 00000001
由原码最高位为1可知,该结果是负数,除符号位外转换成十进制的结果是1,所以最后按位或的结果就是-1。

3、a^b

按位或的结果补码为:11111111 11111111 11111111 11111110
最高位为1,所以是负数。
反码=补码-1,得到反码:11111111 11111111 11111111 11111101
原码=反码除符号位取反,得到原码:10000000 00000000 00000000 00000010
由原码最高位为1可知,该结果是负数,除符号位外转换成十进制的结果是2,所以最后按位或的结果就是-2。

4、~a

取反结果(补码形式):11111111 11111111 11111111 11111000
最高位为1,所以是负数。
反码=补码-1,得到反码:11111111 11111111 11111111 11110111
原码=反码除符号位取反,得到原码:10000000 00000000 00000000 00001000
由原码最高位为1可知,该结果是负数,除符号位外转换成十进制的结果是8,所以最后按位或的结果就是-8。

5、~b

取反结果(补码形式):00000000 00000000 00000000 00000110
最高位为0,所以是正数。正数的原码反码补码都相同,所以转换成十进制结果为6。

2.3. 位运算应用于boolean操作

&(与)、|(或)这两个位运算适用于boolean判断,在这两个运算符的前后的条件都会计算,不像java里的条件判断符&&(并且) ||(或者)会短路,判断符之前的满足条件后,那么判断符之后的表达式不再计算。

public static void main(String[] args) {int a = 5;if (a < 0 & a++ > 0) {}System.out.println("&条件后a=" + a);if (a > 0 | a++ > 0) {}System.out.println("|条件后a=" + a);if (a < 0 && a++ > 0) {}System.out.println("&&条件后a=" + a);if (a > 0 || a++ > 0) {}System.out.println("||条件后a=" + a);
}

输出结果为:

在这里插入图片描述

第一个判断a < 0 & a++ > 0前一个判断已经是false了,但是使用&连接,后一个表达式依然会计算a++,所以输出结果a的值加1等于6。

第二个判断a > 0 | a++ > 0前一个判断已经是true了,但是使用|连接,后一个表达式依然会计算a++,所以输出结果a的值加1等于7。

第三个判断a < 0 && a++ > 0前一个判断已经是false了,使用&&连接的不会再计算后一个表达式的值,所以a的值不变。

第四个判断a > 0 || a++ > 0前一个判断已经是true了,使用||连接的不会再计算后一个表达式的值,所以a的值不变。

3. 移位运算

3.1. 移位运算术语解释

移位运算符含义解释
<<左移补码高位(不包括符号位)去掉指定位数,然后剩下的位数整体向左移动指定位数,低位使用0补齐
>>右移补码低位去掉指定位数,然后剩下的位数整体向右移动指定位数,高位补上符号位(即正数补0,负数补1)
>>>无符号右移这个主要是针对于负数来说的,补码低位去掉指定位数,然后剩下的位数整体向右移动指定位数,高位(包括符号位)全部补上0

移位运算也是基于补码来操作的,因为是采用二进制,所以左移n位相当于该数乘以2的n次方、右移及无符号右移n位相当于该数除以2的n次方,但是无符号右移是相对于负数来说的,把符号位和其他高位都置为0。

3.2. 移位运算示例

我们仍以上面的int a = 7int b = -7举例移位运算的操作。
a的补码二进制为:00000000 00000000 00000000 00000111
b的补码二进制为:11111111 11111111 11111111 11111001
1、a<<2

符号位不变,高位去掉两位,整体左移两位,低两位补0,结果为:
补码:00000000 00000000 00000000 00011100
高位为0即正数,正数的原码反码补码相同,所以原码=补码,转换为十进制结果为:28

2、a>>2

符号位为0,正数,则符号位不变,低位去掉两位,整体右移两位,高两位补0,结果为:
补码:00000000 00000000 00000000 00000001
高位为0即正数,正数的原码反码补码相同,所以原码=补码,转换为十进制结果为:1

3、a>>>2

符号位为0,正数,低位去掉两位,整体右移两位,高两位(包括符号位)补0,结果为:
补码:00000000 00000000 00000000 00000001
高位为0即正数,正数的原码反码补码相同,所以原码=补码,转换为十进制结果为:1

4、b<<2

符号位不变,高位去掉两位,整体左移两位,低两位补0,结果为:
补码:11111111 11111111 11111111 11100100
高位为1即负数
反码=补码-1,得到反码:11111111 11111111 11111111 11100011
原码=反码除符号位取反,得到原码:10000000 00000000 00000000 00011100
由原码最高位为1可知,该结果是负数,除符号位外转换成十进制的结果是28,所以最后按位或的结果就是-28。

5、b>>2

符号位为1,负数,低位去掉两位,整体右移两位,高两位补1,符号位为1,结果为:
补码:11111111 11111111 11111111 11111110
高位为1即负数
反码=补码-1,得到反码:11111111 11111111 11111111 11111101
原码=反码除符号位取反,得到原码:10000000 00000000 00000000 00000010
由原码最高位为1可知,该结果是负数,除符号位外转换成十进制的结果是2,所以最后按位或的结果就是-2。

6、b>>>2

符号位为1,负数,低位去掉两位,高两位(包括符号位)都补0,结果为:
补码:00111111 11111111 11111111 11111110
高位为0即正数,正数的原码反码补码相同,所以原码=补码,转换为十进制结果为:1073741822。

3.3. 移位运算注意事项

1、byteshortchar类型的整数再移位操作时会自动向上转为int类型后再操作移位。
2、int类型占32位,long类型占64位,当对这两个类型移位超出位数时,相当于对要移动的位数取余再移位,例如a<<32位,取余为0,相当于不移动,a<<34,取余为2相当于左移2位。long类型同理,只是对64取余。

4. 应用

1、不利用中间值,交换两个整数
可推导出的结论是a ^ b ^ a = ba ^ b ^ c = a ^ (b ^ c)。所以对于两个整数ab交换可以使用异或位运算。

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

输出结果:

在这里插入图片描述

2、判断一个正数的奇偶性
x & 1 == 0 则为偶数,否则为奇数。因为整数的二进制表示后,最后一位的0和1就表示了该值的奇偶性,&1之后相当于除了最后一位,其他位全清0了,最后一位若是1,则与的结果才为1,说明是奇数,最后一位为0,则与的结果是0,说明是偶数。
3、判断一个正数是不是2的幂次方
使用n&(n-1) == 0则为偶数,否则为奇数。因为2的次方数,除了高位的一个1外,后面的数据全部都是0,也就是说2的次方数的二进制形式里只有一个1,其他全部是0,减1后得到的二进制,1所在位变成0,1后的其他位都会变成1,所以与原二进制每一位都不相同,使用&后结果为0,则可以证明为偶数
4、计算一个二进制数中1的个数

int a = 15;
int count = 0;
while (a != 0) {if ((a & 1) == 1) {count++;}a = a >> 1;
}
System.out.println(count);

输出结果:

在这里插入图片描述

通过&1结果为1,说明最末一位是1,则可通过不断>>1并判断1的个数是否加1,直到这个数的值变为0为止。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/589986.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React16源码: ConcurrentMode的使用及源码实现

ConcurrentMode 1 ) 概述 ConcurrentMode 是 React 16 出来的一个最令人振奋的功能在2018年年初是 Async Mode&#xff0c;在发布了16.6之后&#xff0c;名字进行了更新然后改成了 ConcurrentMode&#xff0c;中间的API有一个过渡的版本&#xff0c;后续会提到它其实是 React…

OpenCV-12绘制图像

OpenCV提供了许多绘制图像的API&#xff0c;可以在图像上绘制各种图形&#xff0c;例如直线&#xff0c;矩形&#xff0c;圆&#xff0c;椭圆等图形。 一、画直线 利用API line&#xff08;img, pt1, pt2, color, thickness, lineType, shift&#xff09;可以绘制直线。 其中…

玩转贝启科技BQ3588C开源鸿蒙系统开发板 —— 代码下载(1)

本文主要参考&#xff1a; BQ3588C_代码下载 1. 安装依赖工具 安装命令如下&#xff1a; sudo apt-get update && sudo apt-get install binutils git git-lfs gnupg flexbison gperf build-essential zip curl zlib1g-dev gcc-multilib g-multiliblibc6-dev-i386 l…

力扣题目学习笔记(OC + Swift)27.移除元素

移除元素 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新…

【编译原理】期末预习做题向I

新的一年希望可以成为更好的人嘿嘿&#xff01; 这一篇基本就是把 up 讲的题都截了一遍然后加了点自己的笔记啥的 O.o &#xff08;不妥的话会删掉的 qwq&#xff0c;希望没事嘿嘿&#xff09; 来源&#xff1a;混子速成 I. 绪论 记住组成部分 II. 前后无关文法和语言 1.…

Python从入门到网络爬虫、自动化

可以创建C、C#、Python、Golang、Java、React、Node、Vue、PHP项目 创建Java项目 创建Python项目 简单if……else……语句 # 简单的if……else……语句 state True if state:print("状态正常") else:print("状态异常")# 复杂的if……elif……语句 score …

粤港澳个人数据跨境流动规则的理解

文章目录 前言一、港澳数据安全的相关背景二、港澳个人数据跨境流动指引三、香港个人资料跨境规则的梳理与解读在本文中主要做以下解读:四、澳门个人资料跨境规则的梳理与解读五、内地与港澳个人数据跨境监管规定比对1、保护目的2、保护对象和监管对象。3、出境活动和出境条件…

周记-20240101

记录一下最近的生活&#xff0c;做一下简单的梳理&#xff0c;具体详细的梳理等我目前的工作步入正轨 以后再开始好好地总结一下2023年的过往经历&#xff0c;总结过去&#xff0c;展望未来。计划一下未来的2024该怎么度过。 最近一阵子都忙着考试&#xff0c;然后从10号以后一…

一骑绝尘!维乐携手骑行侠客轻风逆旅带你解锁冬日逆旅

是逆风冬旅还是冻旅&#xff1f;冬日似乎都被骑友们默认做事应该闭关闭的时间了&#xff0c;空气中萧瑟的寒风仿佛是穿透我们的骨膜&#xff0c;当我还在路上瑟瑟发抖的时候&#xff0c;此时一位公路骑行侠正在开启他的冬日旅途~      以下是来自他的自诉&#xff1a;   …

saas 多租户系统数据隔离方案

关注WX公众号&#xff1a; commindtech77&#xff0c; 获得数据资产相关白皮书下载地址 1. 回复关键字&#xff1a;数据资源入表白皮书 下载 《2023数据资源入表白皮书》 2. 回复关键字&#xff1a;光大银行 下载 光大银行-《商业银行数据资产会计核算研究报告》 3. 回复关键字…

【STM32F103】SysTick系统定时器延时函数

SysTick SysTick是Cortex-M3内核中的一个外设&#xff0c;内嵌在NVIC中&#xff0c;叫系统定时器。 当处理器在调试期间被喊停时&#xff0c;SysTick也将暂停运作。 一共有四个寄存器&#xff0c;不过我们通常用前三个&#xff0c;不需要校准。下图出自《STM32F10xxx Cortex…

关于SIC 的Know-how

SiC的分类和用途 根据电阻率不同&#xff0c;SiC衬底晶片可分为导电型和半绝缘型。 SiC衬底晶片主要用来做成高压功率器件和高频功率器件。其中&#xff0c;导电型SiC衬底晶片经过SiC外延后&#xff08;SiC基SiC外延片&#xff09;&#xff0c;主要应用于制造耐高温、耐高压的…

72内网安全-域横向CSMSF联动及应急响应知识

拿到才行&#xff0c;拿不到就是多余的 案例一MSF&CobaltStrike 联动 Shell 有一些功能可能cs或者msf强大一些&#xff0c;他们两个可以相互调用&#xff0c;在真实情况下也是可以cs和msf同时启动的&#xff0c; cs移交给msf .创建Foreign监听器 “Listeners”“Add”…

蓝桥杯一维差分 | 算法基础

⭐简单说两句⭐ ✨ 正在努力的小新~ &#x1f496; 超级爱分享&#xff0c;分享各种有趣干货&#xff01; &#x1f469;‍&#x1f4bb; 提供&#xff1a;模拟面试 | 简历诊断 | 独家简历模板 &#x1f308; 感谢关注&#xff0c;关注了你就是我的超级粉丝啦&#xff01; &…

Python-docx 深入word源码 带有序号的段落无法设置段后、段前距离、间距等段落属性

如果使用p doc.add_paragraph(内容, styleList Number)来创建序号段落&#xff0c;会发现设置序号段落之间的段前、段后以及段落间距无法生效。后来将docx库生成的word文档打开后发现段落的设置出现问题&#xff0c;如下图红框所示&#xff0c;将该选项去掉即可使段落间距属性…

linux上安装python3.7

1.在liunx上安装python运行环境 yum -y install gcc yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel 2.进入到安装目录 cd /usr/local/ 3.下载python…

【AIGC-图片生成视频系列-4】DreamTuner:单张图像足以进行主题驱动生成

目录 一. 项目概述 问题&#xff1a; 解决&#xff1a; 二. 方法详解 a) 整体结构 b) 自主题注意力 三. 文本控制的动漫角色驱动图像生成的结果 四. 文本控制的自然图像驱动图像生成的结果 五. 姿势控制角色驱动图像生成的结果 2023年的最后一天&#xff0c;发个文记录…

基于Java影院影片管理系统

基于Java影院影片管理系统 功能需求 1、影片信息管理&#xff1a;系统能够添加、删除、修改和查询影片的信息&#xff0c;包括影片名称、导演、演员、类型、简介等。 2、座位管理&#xff1a;系统能够添加、删除、修改和查询影院的座位信息&#xff0c;包括座位号、座位类型…

迈向通用异常检测和理解:大规模视觉语言模型(GPT-4V)率先推出

PAPERCODEhttps://arxiv.org/pdf/2311.02782.pdfhttps://github.com/caoyunkang/GPT4V-for-Generic-Anomaly-Detection 图1 GPT-4V在多模态多任务异常检测中的综合评估 在这项研究中&#xff0c;我们在多模态异常检测的背景下对GPT-4V进行了全面评估。我们考虑了四种模式&#…

BikeDNA(二) OSM数据的内在分析1

BikeDNA&#xff08;二&#xff09; OSM数据的内在分析1 该笔记本分析给定区域的 OSM 自行车基础设施数据的质量。 质量评估是“内在的”&#xff0c;即仅基于一个输入数据集&#xff0c;而不使用外部信息。 对于将 OSM 数据与用户提供的参考数据集进行比较的外在质量评估&…