关于位运算的四则运算
Posted songchengyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于位运算的四则运算相关的知识,希望对你有一定的参考价值。
首先,应该了解一些基本的位运算操作和基础知识:
- <1> 等式 -n = ~ (n-1) = ~n +1 (-n 等于各位取反后加1);
- <2> 获取整数 n 的二进制最后一个1的方法:-n&n 或 (~n+1)&n 或 ~(n-1)&n 如: n=010100 ,则 -n = 101100 ,n&-n = 000100;
- <3> 去掉整数n的二进制最后一个1的方法: n&(n-1) ,如 n= 010100 ,n-1= 010011 ,n&(n-1) = 01000;
- <4> a^b 可以得到没有进位的和 ,a&b可以得到各位产生的进位值。
一:位运算加法
原理:a^b可以得到没有进位的和,(a&b)<<1可以得到进位后的值。
代码1:
//循环控制法 public static int add(int a ,int b){ int temp=0; //当b!=0时,先获取没有进位的和,然后把进位的值赋值给b,直到b==0 while(b!=0){ temp=a; a=a^b; //获取没有进位的和 b=(temp&b)<<1; //把进位的值赋值给b } //当b==0的时候,就不需要进位运算,直接返回结果a return a; }
代码2:
//递归法 public static int add_recursion(int a, int b){ if (b==0) return a; //当b==0时,说明没有需要进位的值,则作为递归的出口 else { int temp=a; a = a ^ b; //获取两个数没有进位的和 b = (temp & b) << 1; //把进位的值赋值给b return add_recursion(a, b); //递归调用 } }
二:位运算减法
原理: a-b = a+(-b) 也就是将位运算的减法转化成为位运算的加法,所以直接v调用位运算的加法即可。(注意-n=~n+1)
代码:
//位运算减法 public static int subduction(int a,int b){ return add(a, add(~b,1)); }
三:位运算乘法
原理: 从乘数的最低位开始到高位,如果遇到1,则把被乘数左移 i 位,进行累加,乘数循环结束后,的恶道的累加和就是结果。
科普: 2*4=8 其中 2 是被乘数,4是乘数 ,一般读作 2乘以4等于8 ,也可以读作2乘4等于8 。
代码1:
//方式1 public static int multiplicative (int a,int b){
int i=0; //定义乘数的低位 (也就是一个数二进制形式的右边开始为低位) int res=0; //累加的结果 //当乘数为0则结束循环 while(b!=0){ //开始处理乘数的当前位从i=0开始,如果遇到1,则累加. if((b&1)==1){ res+=(a<<i); //被乘数左移i位进行累加 b=b>>1; //b右移1位,也就是低位到高位的过程。 i++; //记录当前位是第几位 }else{//如果没有遇到1,则乘数右移一位,不用要累加。 b=b>>1; i++; } } return res; }
代码2:
//方式二 public static int mul(int a, int b){ int ans = 0; //先定义累加的结果】 while (b!=0) {//乘数为0则结束 if ((b & 1)==1) { //如果该乘数&1等于1则对左移后的a进行累加,不等于1则不进行累加 ans = add(ans, a); } //每次循环一次,a=a<<1 ,b=b>>1 a <<= 1; b >>= 1; } return ans; }
四:位运算除法
原理:也就是求a是由多少个b组成的,则我们只需求a能减去多少个b即可,做减法的次数就是除法的商。
代码1:
//方式一(递归) public static int division1(int a,int b) { int res=-1; if(a<b){ return 0; }else{ res=division1(subduction(a, b), b)+1; //a>b说明可以减去,则加一进行统计减去的次数 } return res; }
代码2:
// 方式二 (仅计算正数除法) // 逆推法: 除法就是由乘法的过程逆推,依次减掉(如果a够减的) // b ^ (2 ^ 31), b ^ (2 ^ 30), ...b ^ 8, b ^ 4, b ^ 2, b^1。减掉相应数量的b就在结果加上相应的数量。(注意是b) public static int division(int a, int b) { int ans = 0; // 从最高位开始逆推( 第32位为符号位,所以从第31位开始) for (int i = 31; i >= 0; i--) { // 比较a是否大于b的(1<<i)次方,要避免将a与(b<<i)比较,因为不确定b的(1<<i)次方是否溢出 if ((a >> i)>=b) { // 如果b小于a右移i位,说明足够减去b<<i位的值 ans += (1 << i); //累加,1左移i位的值 a -= (b << i); //减去一次b<<i的值,a不断减小, } } return ans; }
以上是关于关于位运算的四则运算的主要内容,如果未能解决你的问题,请参考以下文章