关于位运算的四则运算

首先,应该了解一些基本的位运算操作和基础知识:

  •   <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 。

扫描二维码关注公众号,回复: 11261697 查看本文章

  代码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;
    }

猜你喜欢

转载自www.cnblogs.com/songchengyu/p/12953530.html