Java位运算实现加减乘除

一、加法

a+b

举例实现:13+9=22

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

只考虑进位结果为10

和刚好是22。

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

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

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

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

算法实现:

1 1 //两种方式: 2 2 //1、递归形式实现 3 3 int add(int a ,int b){ 4 4 if (b == 0) 5 5 return a; 6 6 else{ 7 7 //进位值 8 8 int carry = (a & b) << 1; 9 9 a = a ^b; 1010 return add(a,carry); 1111 } 1212 } 1313 1414 //非递归形式实现 1515 int add2(int a ,int b){ 1616 //进位值 1717 int carry; 1818 while (b != 0){ 1919 carry = (a & b) << 1; 2020 a = a ^b; 2121 b = carry; 2222 } 2323 return a; 2424 }

二、减法

a-b

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

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

算法实现:

11 //减法实现 a+(-b)=a+~b+1 22 int subtraction(int a ,int b){ 33 b = ~b+1; 44 return this.add(a,b); 55 }

三、乘法

a*b

举例说明:

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

算法实现:

1 1 //乘法实现 2 2 //a 被乘数,b 乘数 3 3 int multiplication(int a,int b){ 4 4 int i = 0; 5 5 int res = 0; 6 6 //乘数不为0 7 7 while (b != 0){ 8 8 //处理当前位 9 9 //当前位是1 1010 if ((b & 1) == 1){ 1111 res += (a << i); 1212 b = b >> 1; 1313 //记录当前是第几位 1414 i++; 1515 }else { 1616 //当前位是0 1717 b = b >> 1; 1818 i++; 1919 } 2020 } 2121 return res; 2222 }

四、除法

a/b

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

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

五、测试用例

1 1 package bitOperation; 2 2 3 3 /** 4 4 * @author zsh 5 5 * @company wlgzs 6 6 * @create 2019-02-15 9:46 7 7 * @Describe 位运算实现加减乘除操作 8 8 */ 9 9 public class Test { 1010 //两种方式: 1111 //1、递归形式实现 1212 int add(int a ,int b){ 1313 if (b == 0) 1414 return a; 1515 else{ 1616 //进位值 1717 int carry = (a & b) << 1; 1818 a = a ^b; 1919 return add(a,carry); 2020 } 2121 } 2222 2323 //非递归形式实现 2424 int add2(int a ,int b){ 2525 //进位值 2626 int carry; 2727 while (b != 0){ 2828 carry = (a & b) << 1; 2929 a = a ^b; 3030 b = carry; 3131 } 3232 return a; 3333 } 3434 3535 //减法实现 a+(-b)=a+~b+1 3636 int subtraction(int a ,int b){ 3737 b = ~b+1; 3838 return this.add(a,b); 3939 } 4040 4141 //乘法实现 4242 //a 被乘数,b 乘数 4343 int multiplication(int a,int b){ 4444 int i = 0; 4545 int res = 0; 4646 //乘数不为0 4747 while (b != 0){ 4848 //处理当前位 4949 //当前位是1 5050 if ((b & 1) == 1){ 5151 res += (a << i); 5252 b = b >> 1; 5353 //记录当前是第几位 5454 i++; 5555 }else { 5656 //当前位是0 5757 b = b >> 1; 5858 i++; 5959 } 6060 } 6161 return res; 6262 } 6363 6464 //除法实现 6565 int division(int a,int b){ 6666 int res; 6767 if(a<b){ 6868 return 0; 6969 }else{ 7070 res=division(subtraction(a, b), b)+1; 7171 } 7272 return res; 7373 } 7474 7575 public static void main(String[] args) { 7676 System.out.println(new Test().add(100,8)); 7777 System.out.println(new Test().subtraction(100,8)); 7878 System.out.println(new Test().multiplication(-3,3)); 7979 System.out.println(new Test().division(100,3)); 8080 } 8181 }
点赞
收藏

评论区

加载中...

相关推荐

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

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java中的7个位运算运算符

位运算指的是针对整数的二进制进行的位移操作。位运算提供比算术运算更高的效率,但是位运算的代码可读性较差,建议所有使用位运算的地方写上注释。Java中提供7个位运算符用于位运算。左移(<<)左移运算是将操作数二进制值逐位左移若干位,左移过程中符号位不变,高位溢出则舍弃,低位则补0。范例结果范例结果00000001<<

一篇文章带你弄懂Python基础之进制和数据类型

大家好,我是Go进阶者,今天给大家分享一些Python基础(进制和数据类型),一起来看看吧一、进制1、什么是进制?进制也就是进位计数制,是人为定义的带进位的计数方法(有不带进位的计数方法,比如原始的结绳计数法,唱票时常用的“正”字计数法,以及类似的tallymark计数)。对于任何一种进制X进制,就表示每一位置上的数运算时都是逢X进一位。十进制是逢十进

Python Django开发 经验技巧总结(二)

1.模板中变量的运算(1)加法markup{{value|add:value2}}返回的结果是valuevalue2的值,假设你value为40,value2为60,则该表达式返回结果为100(2)减法markup{{value|addvalue2}}与加法的性质一样,只不过是把第二个参数变成负数进行运算,返回的结果是va

Java位运算实现加减乘除 - HelloWorld