【Java】位运算

这几天刷了一个简单的编程题(将数字变成0的次数)(https://leetcode.cn/problems/number-of-steps-to-reduce-a-number-to-zero/comments/),发现有一种我意想不到的解题思路:位运算。

想起了,最开始上课用C语言学习时,学过位运算。说起位运算,自然要知道源码、反码、补码,这里就不赘述了(主要是我会了)。Java中是否有位运算?当然有。目录如下:

我的实际工作中,大多数情况下只运到了按位与、按位或,其他的似乎没有用到。按照计算机的机制,左移和右移会比加减乘除的效率高。

不过,以我个人的观点:在我有限的低级工作中,并没有因为使用的是加减乘除,而不是位移照成卡死。这种情况下,让别人更好理解的方式理解更重要。不过,务实基础,或者作为奇技淫巧,比赛和和人吹牛时,展示出来:我比多想到一种效率更高的方法,我基础比你好。

闲言少叙,接下来我们看看Java的位运算吧。

按位与(&)

System.out.println(5&3);        // 结果为1

 Why? 我们来进行二进制比较:

按位或(|)

Java代码如下:

System.out.println(5|3);        // 结果为7

 运行原理如下:

按位取反(~)

Java按位取反代码如下:

System.out.println(~5);        // 结果为-6

原理如下图:

按位异或(^)

异或:相同的取0 ,相反取1

JAVA的异或运算代码如下:

System.out.println(5^3);        // 结果为6

原理如下图:

左移(<<)

说道左移和右移,不知道有没有小伙伴和我一样,经常搞错方向。有时候会蒙圈。到底左移表示的是乘法,还是除法?想想看,你走在一条人生的分叉路上,有两条分别向左右的路。

所以,左移 << 和右移 >> 括号尖头的方向都是箭头的方向。左边是高位,往左移动,就是向更高更大的方向走,即相当于乘法;右边是低位,往右移动,就是向更低更小的方向走,即除法。

题外话:《闻王昌龄左迁龙标遥有此寄》的“左”,与左移的左意思相反。

Java 代码如下:

System.out.println(5<<2);       // 20 : 相当于5*(2^2)

运行的原理图如下:

 左移后,低位补0。

右移(>>)

Java代码如下:

System.out.println(5>>2);       // 1 : 相当于5/(2^2)

运行的原理图如下:

 被挤出去的1,不得不消失;高位补0。

无符号右移(>>>)

右移和无符号右移有什么区别?用正数做例子可能无法表示。那么用负数来表示吧。

 可以发现当负数的时候,右移高位补1,无符号右移高位补1。

至于为什么呢?(右移我们把它想象成除法,就能理解了。至于无符号右移,那么就把它当作-5的无符号数对应的正数,前面自然补0)

所以,java代码如下:

1 System.out.println(-5>>2);      // -2
2 System.out.println(-5>>>2);     // 1073741822

 

posted @ 2023-08-29 18:48  陆陆无为而治者  阅读(34)  评论(0编辑  收藏  举报