Java位运算实现加减乘除

Wesley13
• 阅读 758

一、加法

a+b

举例实现:13+9=22

13+9不考虑进位结果为12

只考虑进位结果为10

和刚好是22。

13二进制为1101,9二进制为1001。

不考虑进位结果为0100。算式为a^b

只考虑进位结果为10010。算式为(a&b)<< 1

然后它俩继续进行运算,直到进位为0。

算法实现:

 1 //两种方式:
 2     //1、递归形式实现
 3     int add(int a ,int b){
 4         if (b == 0)
 5             return a;
 6         else{
 7             //进位值
 8             int carry = (a & b) << 1;
 9             a = a ^b;
10             return add(a,carry);
11         }
12     }
13 
14     //非递归形式实现
15     int add2(int a ,int b){
16         //进位值
17         int carry;
18         while (b != 0){
19             carry = (a & b) << 1;
20             a = a ^b;
21             b = carry;
22         }
23         return a;
24     }

二、减法

a-b

先来证明一个等式。Java负数存储是以补码形式存储的(补码=反码+1)。所以反码=补码-1.即~n=-n-1=-(n+1)

所以a-b可以化简为a+(-b)=a+~b+1

算法实现:

1 //减法实现 a+(-b)=a+~b+1
2     int subtraction(int a ,int b){
3         b = ~b+1;
4         return this.add(a,b);
5     }

三、乘法

a*b

举例说明:

Java位运算实现加减乘除

  可以看到,二进制乘法的原理是:从乘数的低位到高位,遇到1并且这个1在乘数的右起第i(i从0开始数)位,那么就把被乘数左移i位得到 temp_i 。直到乘数中的1遍历完后,把根据各位1而得到的被乘数的左移值们 temp_i 相加起来即得乘法结果。那么根据这个原理,可以得到实现代码:这里要点为:用i记录当前遍历的乘数位,当前位为1则被乘数左移i位并加到和中,同时i++处理下一位;为0则乘数右移,i++,处理下一位......直到乘数==0说明乘数中的1遍历完了。此时把和返回即可。

算法实现:

 1 //乘法实现
 2     //a 被乘数,b 乘数
 3     int multiplication(int a,int b){
 4         int i = 0;
 5         int res = 0;
 6         //乘数不为0
 7         while (b != 0){
 8             //处理当前位
 9             //当前位是1
10             if ((b & 1) == 1){
11                 res += (a << i);
12                 b = b >> 1;
13                 //记录当前是第几位
14                 i++;
15             }else {
16                 //当前位是0
17                 b = b >> 1;
18                 i++;
19             }
20         }
21         return res;
22     }

四、除法

a/b

除法的意义就在于:求a可以由多少个b组成。那么由此我们可得除法的实现:求a能减去多少个b,做减法的次数就是除法的商。

 1 //除法实现
 2     int division(int a,int b){
 3         int res;
 4         if(a<b){
 5             return 0;
 6         }else{
 7             res=division(subtraction(a, b), b)+1;
 8         }
 9         return res;
10     }

五、测试用例

 1 package bitOperation;
 2 
 3 /**
 4  * @author zsh
 5  * @company wlgzs
 6  * @create 2019-02-15 9:46
 7  * @Describe 位运算实现加减乘除操作
 8  */
 9 public class Test {
10     //两种方式:
11     //1、递归形式实现
12     int add(int a ,int b){
13         if (b == 0)
14             return a;
15         else{
16             //进位值
17             int carry = (a & b) << 1;
18             a = a ^b;
19             return add(a,carry);
20         }
21     }
22 
23     //非递归形式实现
24     int add2(int a ,int b){
25         //进位值
26         int carry;
27         while (b != 0){
28             carry = (a & b) << 1;
29             a = a ^b;
30             b = carry;
31         }
32         return a;
33     }
34 
35     //减法实现 a+(-b)=a+~b+1
36     int subtraction(int a ,int b){
37         b = ~b+1;
38         return this.add(a,b);
39     }
40 
41     //乘法实现
42     //a 被乘数,b 乘数
43     int multiplication(int a,int b){
44         int i = 0;
45         int res = 0;
46         //乘数不为0
47         while (b != 0){
48             //处理当前位
49             //当前位是1
50             if ((b & 1) == 1){
51                 res += (a << i);
52                 b = b >> 1;
53                 //记录当前是第几位
54                 i++;
55             }else {
56                 //当前位是0
57                 b = b >> 1;
58                 i++;
59             }
60         }
61         return res;
62     }
63 
64     //除法实现
65     int division(int a,int b){
66         int res;
67         if(a<b){
68             return 0;
69         }else{
70             res=division(subtraction(a, b), b)+1;
71         }
72         return res;
73     }
74 
75     public static void main(String[] args) {
76         System.out.println(new Test().add(100,8));
77         System.out.println(new Test().subtraction(100,8));
78         System.out.println(new Test().multiplication(-3,3));
79         System.out.println(new Test().division(100,3));
80     }
81 }
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Irene181 Irene181
3年前
一篇文章带你弄懂Python基础之进制和数据类型
大家好,我是Go进阶者,今天给大家分享一些Python基础(进制和数据类型),一起来看看吧一、进制1、什么是进制?进制也就是进位计数制,是人为定义的带进位的计数方法(有不带进位的计数方法,比如原始的结绳计数法,唱票时常用的“正”字计数法,以及类似的tallymark计数)。对于任何一种进制X进制,就表示每一位置上的数运算时都是逢X进一位。十进制是逢十进
Wesley13 Wesley13
3年前
java中的7个位运算运算符
位运算指的是针对整数的二进制进行的位移操作。位运算提供比算术运算更高的效率,但是位运算的代码可读性较差,建议所有使用位运算的地方写上注释。Java中提供7个位运算符用于位运算。左移(<<)左移运算是将操作数二进制值逐位左移若干位,左移过程中符号位不变,高位溢出则舍弃,低位则补0。范例结果范例结果00000001<<
CuterCorley CuterCorley
3年前
Python Django开发 经验技巧总结(二)
1.模板中变量的运算(1)加法markup{{value|add:value2}}返回的结果是valuevalue2的值,假设你value为40,value2为60,则该表达式返回结果为100(2)减法markup{{value|addvalue2}}与加法的性质一样,只不过是把第二个参数变成负数进行运算,返回的结果是va
九路 九路
4年前
Java判断一个数是不是快乐数
快乐数的定义:快乐数(happynumber)有以下的特性:在给定的进位制下,该数字所有数位(digits)的平方和,得到的新数再次求所有数位的平方和,如此重复进行,最终结果必为1。以十进制为例:28→2²8²68→6²8²100→1²0²0²132→3²2²13→1²3²10→1²0²137→3
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Stella981 Stella981
3年前
20180109Java位运算
一,Java位运算1.表示方法:  在Java语言中,二进制数使用补码表示,最高位为符号位,正数的符号位为0,负数为1。补码的表示需要满足如下要求。 (1)正数的最高位为0,其余各位代表数值本身(二进制数)。 (2)对于负数,通过对该数绝对值的补码按位取反,再对整个数加1。 2.位运算符位运算表达式由
可莉 可莉
3年前
20180109Java位运算
一,Java位运算1.表示方法:  在Java语言中,二进制数使用补码表示,最高位为符号位,正数的符号位为0,负数为1。补码的表示需要满足如下要求。 (1)正数的最高位为0,其余各位代表数值本身(二进制数)。 (2)对于负数,通过对该数绝对值的补码按位取反,再对整个数加1。 2.位运算符位运算表达式由
Wesley13 Wesley13
3年前
Java实现大数乘法运算
基本思路:将输入的两个大数以字符串的形式存储,然后转化成整型数组存储,通过整型数组进行乘法运算(采用分治的思想)即乘法分配律,如AB\CDAC(ADBC)BD,将两个数组逐位相乘的结果对位存放在新的数组里,再对新数组进行进位判定,进位结束后将新数组转化成字符串输出。实现代码如下:importjava.util.Scanner;