zoukankan      html  css  js  c++  java
  • 位运算实现整数的加减乘数运算

    用位运算实现加法也就是计算机用二进制进行运算,32位的CPU只能表示32位内的数,这里先用1位数的加法来进行,在不考虑进位的基础上,如下

    1. 1 + 1 = 0
    2. 1 + 0 = 1
    3. 0 + 1 = 1
    4. 0 + 0 = 0

    很明显这几个表达式可以用位运算的“^”来代替,如下

    1. 1 ^ 1 = 0
    2. 1 ^ 0 = 1
    3. 0 ^ 1 = 1
    4. 0 ^ 0 = 0

    这样我们就完成了简单的一位数加法,那么要进行二位的加法,这个方法可行不可行呢?肯定是不行的,矛盾就在于,如何去获取进位?要获取进位我们可以如下思考:

    1. 0 + 0 = 0
    2. 1 + 0 = 0
    3. 0 + 1 = 0
    4. 1 + 1 = 1
    5. //换个角度看就是这样
    6. 0 & 0 = 不进位
    7. 1 & 0 = 不进位
    8. 0 & 1 = 不进位
    9. 1 & 1 = 进位

    正好,在位运算中,我们用“<<”表示向左移动一位,也就是“进位”。那么我们就可以得到如下的表达式

    1. //进位可以用如下表示:
    2. (x&y)<<1

    到这里,我们基本上拥有了这样两个表达式

    1. x^y //执行加法
    2. (x&y)<<1 //进位操作

    我们来做个2位数的加法,在不考虑进位的情况下

    1. 11+01 = 100  // 本来的算法
    2.  
    3. // 用推算的表达式计算
    4. 11 ^ 01 = 10
    5.  
    6. (11 & 01) << 1 = 10
    7.  
    8. //到这里 我们用普通的加法去运算这两个数的时候就可以得到 10 + 10 = 100
    9. //但是我们不需要加法,所以要想别的方法,如果让两个数再按刚才的算法计算一次呢
    10.  
    11. 10 ^ 10 = 00
    12.  
    13. (10 & 10) << 1 = 100

    到这里基本上就得出结论了,其实后面的那个 “00” 已经不用再去计算了,因为第一个表达式就已经算出了结果。

    继续推理,直至进位补偿为0。



    	/**
    	 * 两个正整数相加
    	 * 
    	 * @param a
    	 * @param b
    	 * @return
    	 */
    	public static int aplusb(int a, int b) {
    		//用异或模拟不带进位的加法
    		int xor = a ^ b;
    		//用按位与模拟是否进位,左移1位代表进位补偿
    		int and = (a & b) << 1;
    		
    		//进位补偿不断左移直至为0,则运算停止
    		while (and != 0) {
    			//不带进位加法
    			int sum = xor ^ and;
    			//获得进位补偿
    			and=(xor&and)<<1;
    			
    			xor=sum;
    		}
    		return xor;
    	}
    	
    	/**
    	 * 两个正整数相加的递归算法
    	 */
    	public static int aplusbPro(int a,int b) {
    		if(b==0) {
    			return a;
    		}
    		return aplusbPro(a^b,(a&b)<<1);
    	}
    	
    	/**
    	 * 实现整数的相乘
    	 */
    	public static int amultibPro(int a,int b) {
    		int sum=0;
    		while(b!=0) {
    			if((b&1)!=0)//取最后一位 是否为0
    				sum=aplusb(a,sum);
    			a<<=1;
    			b>>=1;
    		}
    		
    		return sum;
    	}
    	
    	/**
    	 * 递归实现整数相乘
    	 */
    	public static int amultib(int a,int b) {
    		return b==1?a:aplusb(amultib(a,b-1),a);//a*(b-1)+a
    	}


    测试发现:基本的算数运算在计算机底层其实就是通过位运算完成的,因此位运算实现的基本运算的效率和运算符等同

    例如加法运算




    乘法运算,在计算机底层会对被乘数,乘数做优化。当乘数大于被乘数时,会交替两者的位置,以减少运算次数,提升运算速度

    优化前:



    优化后




    相关文章:1.用位运算实现四则运算之加减乘除

      2.位运算 实现加法

      3.用位运算实现四则运算之加减乘除(用位运算求一个数的1/3)


  • 相关阅读:
    POJ 1753
    POJ 3669
    POJ 1979
    HDU 1372
    Codeforces 761D
    response下载csv文件内容乱码问题
    只要没有给String[]数组new 空间,那么他就只是一个引用
    servlet中的“/”代表当前项目,html中的“/”代表当前服务器
    onkeyup的死循环问题
    OPGL+VS2017+GLFW+GLEW配置详细步骤
  • 原文地址:https://www.cnblogs.com/chenny3/p/10226126.html
Copyright © 2011-2022 走看看