zoukankan      html  css  js  c++  java
  • 关于位运算的四则运算

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

    •   <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;
        }
  • 相关阅读:
    重构项目使用Spring+Hibernate+HibernateAnnotation+GenericDao技术
    java调用bat
    Redis快速入门
    PDF中添加页面/合并 PDF 内容
    eclipse+webservice开发实例
    MYSQL Migration Toolkit 安装
    从CSDN搬家到博客园
    The server does not support version 3.0 of the J2EE Web module specification
    HibernateAnnotation入门实例
    github使用总结
  • 原文地址:https://www.cnblogs.com/songchengyu/p/12953530.html
Copyright © 2011-2022 走看看