您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

想看懂源码必须会的位逻辑运算符

时间:2023-04-07 13:54:47  来源:微信公众号  作者:JAVA旭阳

概述

最近在看jdk一些集合的框架的时候,频繁出现位运算,比如下图,这对我阅读源码产生了很大的阻碍,因为我对这块内容也是一知半解,因为很少用过,即便学过基本也还给老师了,这篇文章主要针对JAVA中的位运算做一个总结。

图片

位运算符介绍

在Java语言中,提供了7种位运算符,分别是按位与(&)、按位或(|)、按位异或(^)、取反(~)、左移(<<)、带符号右移(>>)和无符号右移(>>>)。位运算符是对long、int、short、byte和char这5种类型的数据进行运算的,我们不能对double、float和boolean进行位运算操作。

位运算符只要是正对二进制的数据进行操作,由于java中最终是按照补码的方式存储的,至于为什么按照补码的方式,是另外一个话题了,按下不表。

正数的原码和反码、补码一样。负数的反码:把原码的符号位保持不变,数值位逐位取反,即可得原码的反码。负数的补码:在反码的基础上加 1 即得该原码的补码。

位逻辑运算符

位逻辑运算符有以下4种,按位与(&)、按位或(|)、按位异或(^)、取反(~)。

位与(&)运算符

位与运算符为&,运算规则是:参与运算的数字,低位对齐,高位不足的补零,如果对应的二进制位同时为 1,那么计算结果才为 1,否则为 0。因此,任何数与 0 进行按位与运算,其结果都为 0,最左边的符号位也是要参与运算的。

图片

例子:5&6

图片

首先把5和6这两个数字转换为补码,之后还要把这两个数字按位对齐,然后一一把两个相应的二进制位上的数字进行按位与运算,运算得到的二进制串就是最终的结果。

通过位与运算符特点推导出如下结论:

  1. 任何数与 0 进行按位与运算,其结果都为 0

位或(|)运算符

位或运算符为|,其运算规则是:参与运算的数字,低位对齐,高位不足的补零。如果对应的二进制位只要有一个为 1,那么结果就为 1;如果对应的二进制位都为 0,结果才为 0。

图片

例子: 5|6

图片

首先还是把这两个数字转换成补码形式,之后把相应的二进制位上的数字进行按位或运算:如果两个二进制数都是0,计算结果为0,其他情况计算结果均为1。按照这个规则把每一位上的数字都计算一遍后,得到二进制的运算结果是111,这个运算结果转换为十进制数是7。

通过位或运算符特点推导出如下结论:

  1. 任何数与 0 进行按位或运算,其结果都是它本身
  2. 任何数与 位数都是1的二进制进行按位或运算,其结果的二进制位数都是1

位异或(^)运算符

位异或运算符为^,其运算规则是:参与运算的数字,低位对齐,高位不足的补零,如果对应的二进制位相同(同时为 0 或同时为 1)时,结果为 0;如果对应的二进制位不相同,结果则为 1。

图片

例子:5^6

图片

同样是先转成补码,然后异或计算,得到最后的二进制结果11,转成十进制为3。

通过异或运算符特点推导出如下结论:

  1. 异或运算符满足交换律,a^b与b^a是等价的。
  2. 任何两个相同的数字进行异或操作,所得到的结果都必然为0。
  3. 对于任意一个二进制位来说,这个位上的数与0进行异或运算,运算结果与这个二进制位上的数是相同的,而与1进行异或运算,结果与这个二进制位上的数字相反。
  4. 对于任何两个整数a和b,a^b^b等于a, 对于任何两个整数a和b,a^b^a等于b

位取反(~)运算符

位取反运算符为~,其运算规则是:只对一个操作数进行运算,将操作数二进制中的 1 改为 0,0 改为 1。

例子:对数字5取反

图片

首先把数字5转换成补码形式,之后把每个二进制位上的数字进行取反,如果是0就变成1,如果1就变成0,经过取反后得到的二进制串就是运算结果,此时是补码的形式,需要转回原码,符号位为1,其余各位取反,然后再整个数加1, 这个运算结果被还原为十进制数是-6。

注意:位运算符的操作数只能是整型或者字符型数据以及它们的变体,不用于 float、double 或者 long 等复杂的数据类型。

位移位运算符

位移相关的运算符有三个,分别是左移(<<)、带符号右移(>>)、无符号右移(>>>)。

左移运算符

左移位运算符为<<,其运算规则是:按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。

图片

根据左移运算符可以推导出:

  1. 左移运算有乘以2的N次方的效果。一个数向左移动1位,就相当于乘以2的1次方,移动两位就相当于乘以2的2次方,也就是乘以4。

带符号右移运算符

右位移运算符为>>,其运算规则是:符号位不变,按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补零。

图片

根据带符号右移运算符特点可以推导出:

  1. 对于正数而言,带符号右移之后产生的数字确实等于除以2的N次方。
  2. 对于任何一个byte、short或者int类型的数据而言,带符号右移31位之后,得到的必然是0或者是-1。对于long类型的数据而言,带符号右移63位之后,得到的也必然是0或者是-1。

无符号右移

无符号右移运算符为>>>, 其运算规则是:无符号右移在二进制串移动之后,空位由0来补充,与符号位是0还是1毫无关系,注意这里的无符号是忽略符号位,也参与移位。

图片

常见的位运算

  1. 计算m*2^n
System.out.println("2^3=" + (1 << 3));// 2^3=8
System.out.println("3*2^3=" + (3 << 3));// 3*2^3=24
System.out.println("5*2^3=" + (5 << 3));// 5*2^3=40
  1. 判断一个数n的奇偶性
 
System.out.println((5 & 1) == 1 ? "奇数" : "偶数"); // 奇数
System.out.println((6 & 1) == 1 ? "奇数" : "偶数"); // 偶数
System.out.println((0 & 1) == 1 ? "奇数" : "偶数"); // 偶数
System.out.println((-1 & 1) == 1 ? "奇数" : "偶数"); // 奇数
System.out.println((-2 & 1) == 1 ? "奇数" : "偶数"); // 偶数
  1. 取绝对值
System.out.println((-5 ^ (-5 >> 31)) - (-5 >> 31));// 5
System.out.println((0 ^ (0 >> 31)) - (0 >> 31));// 0

4个字节 32位,a>>31取得a的符号;

任何正数右移31后只剩符号位0,溢出的31位截断,空出的31位补符号位0,最终结果为0;

任何负数右移31后只剩符号位1,溢出的31位截断,空出的31位补符号位1,最终结果为 -1;

正数 ^ 0 = 正数本身(二进制不变);

负数 ^ -1 = 它的绝对值 -1(二进制翻转每一位);

总结

位运算符这块个人觉得还是挺复杂的,还是需要不断的加深学习和理解。这里强调一点,位运算计算后,不会影响值得本身,比如 int a=5; ~a; 这个a本身并没有改变。另一方面,位运算的效率是远远大于直接计算的。



Tags:运算符   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
MySQL算术运算符使用详解
简介MySQL是一种流行的开源关系型数据库管理系统,广泛用于各种应用程序和网站的数据存储和管理。在MySQL中,算术运算符是执行数学计算的特殊符号,用于处理数字类型的数据。本文...【详细内容】
2023-08-20  Search: 运算符  点击:(276)  评论:(0)  加入收藏
MySQL逻辑运算符使用详解
简介在MySQL中,逻辑运算符用于处理布尔类型的数据,进行逻辑判断和组合条件。逻辑运算符主要包括AND、OR、NOT三种,它们可以帮助我们在查询和条件语句中进行复杂的逻辑操作。本...【详细内容】
2023-08-20  Search: 运算符  点击:(234)  评论:(0)  加入收藏
Python中的海象运算符到底是什么?
Python中的海象运算符到底是什么?最近在Twitter上看到了一段很有意思的Python代码,使用了一个叫做海象运算符的东西。代码如下:>>> (a := 1)>>> (a, b := 2, 3)>>> print(f&#39...【详细内容】
2023-05-24  Search: 运算符  点击:(130)  评论:(0)  加入收藏
关系运算符与逻辑运算符及其表达式,运算符的优先级
关系运算符C#中的关系运算符(又称为比较运算符) 作用是对运算符两侧的操作数(包括变量,表达式等)进行比较,得到一个比较后的结果,其结果是布尔型只有true或false。常用做选...【详细内容】
2023-04-10  Search: 运算符  点击:(366)  评论:(0)  加入收藏
想看懂源码必须会的位逻辑运算符
概述最近在看jdk一些集合的框架的时候,频繁出现位运算,比如下图,这对我阅读源码产生了很大的阻碍,因为我对这块内容也是一知半解,因为很少用过,即便学过基本也还给老师了,这篇文章...【详细内容】
2023-04-07  Search: 运算符  点击:(201)  评论:(0)  加入收藏
为什么 Python、Go 和 Rust 都不支持三元运算符?
在编程时,我们经常要作条件判断,并根据条件的结果选择执行不同的语句块。在许多编程语言中,最常见的写法是三元运算符,但是,Python 并不支持三元运算符,无独有偶,两个最热门的新兴...【详细内容】
2023-04-03  Search: 运算符  点击:(279)  评论:(0)  加入收藏
Java中的自增自减运算符
注意事项1.单独使用的时候,++和--无论是放在变量的前边还是后边,结果是一样的。 例子: a++ //两个结果一样...【详细内容】
2022-09-21  Search: 运算符  点击:(528)  评论:(0)  加入收藏
为什么 Python、Ruby 等语言弃用了自增运算符?
不知道你是否曾疑惑过这个问题:为什么 Python 中没有自增自减操作呢?两年前,猫哥我在“Python为什么”系列中探讨过这个话题()。今天分享的文章也是关于这个话题,而且非常详细,推荐...【详细内容】
2022-08-03  Search: 运算符  点击:(175)  评论:(0)  加入收藏
JavaScript 空值合并运算符
现实开发中,经常会有判断变量是否被定义的需求,然后根据它进行相应的操作:let visitor1 = &#39;Kylin&#39;console.log(visitor1 ?? &#39;访客&#39;) // Kylinlet visitor2cons...【详细内容】
2022-05-11  Search: 运算符  点击:(400)  评论:(0)  加入收藏
C语言有大约40个运算符,最常用的有这些
5.2 基本运算符C用运算符(operator)表示算术运算。例如,+运算符使在它两侧的值加在一起。如果你觉得术语“运算符”很奇怪,那么请记住东西总得有个名称。与其叫“那些东西”或...【详细内容】
2021-02-25  Search: 运算符  点击:(650)  评论:(0)  加入收藏
▌简易百科推荐
Netflix 是如何管理 2.38 亿会员的
作者 | Surabhi Diwan译者 | 明知山策划 | TinaNetflix 高级软件工程师 Surabhi Diwan 在 2023 年旧金山 QCon 大会上发表了题为管理 Netflix 的 2.38 亿会员 的演讲。她在...【详细内容】
2024-04-08    InfoQ  Tags:Netflix   点击:(0)  评论:(0)  加入收藏
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(6)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(13)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(9)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(5)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(11)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(9)  评论:(0)  加入收藏
为什么都说 HashMap 是线程不安全的?
做Java开发的人,应该都用过 HashMap 这种集合。今天就和大家来聊聊,为什么 HashMap 是线程不安全的。1.HashMap 数据结构简单来说,HashMap 基于哈希表实现。它使用键的哈希码来...【详细内容】
2024-03-22  Java技术指北  微信公众号  Tags:HashMap   点击:(11)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  机器之心Pro    Tags:LoRA   点击:(12)  评论:(0)  加入收藏
这样搭建日志中心,传统的ELK就扔了吧!
最近客户有个新需求,就是想查看网站的访问情况。由于网站没有做google的统计和百度的统计,所以访问情况,只能通过日志查看,通过脚本的形式给客户导出也不太实际,给客户写个简单的...【详细内容】
2024-03-20  dbaplus社群    Tags:日志   点击:(4)  评论:(0)  加入收藏
站内最新
站内热门
站内头条