Java利用位运算实现加减运算详解
前言
本文主要介绍如何使用位运算来实现加减功能,也就是在整个运算过程中不能出现加减符号。
加减乘除运算在计算机中,实际上都是用位运算实现的,今天就用位运算来模拟下加法和减法的运算功能。
思路分析
先分析如何用位运算实现加法运算。
示例
假设a=23
,b=36
,使用位运算实现加法得到结果59
。
首先来看下23
、36
、59
的二进制信息。
从上面的图中可以看到,两个数相加的结果与两个数异或的结果很相似,只不过在图中的2位置相加的时候,产生了进位,而异或是没有进位的,如果能拿到进位信息,把两个数异或的结果和进位信息的结果相加就能得到最终结果了,那么如果能拿到进位信息呢?
位运算进位
上图中,59
的二进制信息可以分为两部分,0110011
和 0001000
,再结合23
、36
的二进制信息来看,0110011
为23
和36
的异或结果,而23
和36
相与的结果跟0001000
很相似,只不过0001000
中的1
比相与结果往前移了一位。
于是,我们可以得出,两个数的二进制进位信息为两个数的相与在左移一位。
初步结果
经过上面的分析,我们可以得到了一个初步的运算结果,即两个数相加等于两个数异或加上两个数的相与左移1位,也就是a + b = (a ^ b) + ((a & b) << 1)
。
先用23
和36
来验证下。
经过验证可以看到,刚才得出的结论是正确的。
但是,我们要做到在整个运算过程中不能出现加号,接下来要想办法把这个加号给去掉。
去除加号
还是以23
和36
为例,经过上面的运算我们把运算的位运算结果给化简下。
23 + 36 = (23 ^ 36) + ((23 & 36) << 1) = 51 + 8
也就是把23
和36
的相加运算转化为了51
和8
的相加运算,接下来继续分析51
和8
的相加运算,也是通过异或和相与进行操作。
51 + 8 = (51 ^ 8) + ((51 & 8) << 1) = 59 + 0
嗯?可以发现我们已经得出59
了,而且还加了个0
,加了个0
不就相当于加了个寂寞嘛,可以直接省略啊。
由此,我们又可以得出一个结论,两个数的二进制进位信息为两个数的相与在左移一位,不停地循环这个过程,直到有一个数变为0,就能得到结果。
整体思路
现在来总结下整体的计算过程:
- 把两个数相加,拆分成两步,两个数异或加上两个数相与左移1位。
- 判断相与左移的结果是否为0。
- 如果相与左移为0,两个数异或的结果即为相加的结果。
- 如果相与左移结果不为0,把得到的新结果,重复执行第1~3步操作。
加法代码实现
经过上面的分析,来看下代码实现。
public class Code19_Add { public static int add(int a, int b) { int sum = 0; while (b != 0) { sum = a ^ b; b = (a & b) << 1; a = sum; } return sum; } public static void main(String[] args) { int sum = add(23, 36); System.out.println(sum); } }
运行程序,输出结果为59。
减法实现
减法分析
还是以23
和36
为例,如果要计算 36 - 23
,该怎么办?
36 - 23
不就相当于36 + (-23)
,可以理解为加上一个负数,这就可以了吗?不不不,要求的是不能出现加减符号,-23
里面是有减法这个符号的。
还记得前面我们分析的负数可以怎么表示吗?对了,负数是对一个数的取反再加1。嗯?又出现加号了,不过加法我们不是已经实现了吗?直接拿来用就好了。
减法代码实现
有了加法操作,减法就很简单了,来看下代码。
public class Code20_Sub { public static int add(int a, int b) { int sum = 0; while (b != 0) { sum = a ^ b; b = (a & b) << 1; a = sum; } return sum; } public static int sub(int a, int b) { return add(a, add(~b, 1)); } public static void main(String[] args) { int sum = sub(36, 23); System.out.println(sum); } }
运行一下输出结果为13
。
嗯,Perfect!
总结
本文主要介绍如何使用位运算来实现加减功能,至此功能都已经实现了。
那么问题来了,我们实现的加减运算与Java本身的加减相比,谁的效率更高呢?当然是Java中的更高了,因为我们是用Java实现的,代码运行后,要经过层层的翻译才能到达底层,所以效率肯定是有损失的。
当然我们的目的是熟悉位运算的操作,这个才是最重要的。
到此这篇关于Java利用位运算实现加减运算详解的文章就介绍到这了,更多相关Java位运算实现加减运算内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
原文出处:https://juejin.cn/post/7183115929226575928
相关文章
- 这篇文章主要介绍了如何利用java语言实现经典《复杂迷宫》游戏,文中采用了swing技术进行了界面化处理,感兴趣的小伙伴可以动手试一试...2022-02-01
java 运行报错has been compiled by a more recent version of the Java Runtime
java 运行报错has been compiled by a more recent version of the Java Runtime (class file version 54.0)...2021-04-01- 这篇文章主要介绍了在java中获取List集合中最大的日期时间操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
- 这篇文章主要介绍了教你怎么用Java获取国家法定节假日,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下...2021-04-23
- 这篇文章主要介绍了Java如何发起http请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-31
- 说起C#和Java这两门语言(语法,数据类型 等),个人以为,大概有90%以上的相似,甚至可以认为几乎一样。但是在工作中,我也发现了一些细微的差别...2020-06-25
- 这篇文章主要介绍了解决Java处理HTTP请求超时的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-29
- 这篇文章主要介绍了java 判断两个时间段是否重叠的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
- 这篇文章主要介绍了超简洁java实现双色球若干注随机号码生成(实例代码),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-02
java 画pdf用itext调整表格宽度、自定义各个列宽的方法
这篇文章主要介绍了java 画pdf用itext调整表格宽度、自定义各个列宽的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-31- 这篇文章主要介绍了Java生成随机姓名、性别和年龄的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-01
- 这篇文章主要给大家介绍了关于C#位运算以及实例计算的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-06-25
- 这篇文章主要介绍了java正则表达式判断前端参数修改表中另一个字段的值,需要的朋友可以参考下...2021-05-07
Java使用ScriptEngine动态执行代码(附Java几种动态执行代码比较)
这篇文章主要介绍了Java使用ScriptEngine动态执行代码,并且分享Java几种动态执行代码比较,需要的朋友可以参考下...2021-04-15- 这篇文章主要介绍了Java开发实现人机猜拳游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-03
- 这篇文章主要介绍了Java List集合返回值去掉中括号('[ ]')的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-29
Java中lombok的@Builder注解的解析与简单使用详解
这篇文章主要介绍了Java中lombok的@Builder注解的解析与简单使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-06- 下面小编就为大家带来一篇java中String类型变量的赋值问题介绍。小编觉得挺不错的。现在分享给大家,给大家一个参考。...2016-03-28
Java 8 Stream 的终极技巧——Collectors 功能与操作方法详解
这篇文章主要介绍了Java 8 Stream Collectors 功能与操作方法,结合实例形式详细分析了Java 8 Stream Collectors 功能、操作方法及相关注意事项,需要的朋友可以参考下...2020-05-20- 这篇文章主要介绍了Java线程池中的各个参数如何合理设置操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-19