用位运算实现两个整数的加减乘除运算

来源:互联网 发布:structure软件 k值 编辑:程序博客网 时间:2024/05/18 03:39

以下的内容经过了自己的整理:

      /************************************************************************
*   程序功能:不用加减乘除做加法题目:写一个函数,求两个整数之和
*   输入:整数num1,num2
    输出:2个数之和
*   思路:5的二进制是101,17的二进制是10001。
把计算分成三步:
第一步各位相加但不计进位,得到的结果是10100(最后一位两个数都是1,相加的结果是二进制的10。
这一步不计进位,因此结果仍然是0);
第二步记下进位。在这个例子中只在最后一位相加时产生一个进位,结果是二进制的10;
第三步把前两步的结果相加,得到的结果是10110,转换成十进制正好是22。
由此可见三步走的策略对二进制也是适用的。
于是把二进制的加法用位运算来替代:
(1)第一步不考虑进位对每一位相加。0加0、1加1的结果都0,0加1、1加0的结果都是1。
 这和异或的结果是一样的。对异或而言,0和0、1和1异或的结果是0,而0和1、l和0的异或结果是1。
(2)考虑第二步进位,对0加0、0加1、1加0而言,都不会产生进位,只有1加1时,会向前产生一个进位。
此时我们可以想象成是两个数先做位与运算,然后再向左移动一位。只有两个数都是1的时候, 位与得到
的结果是1,其余都是0。第三步把前两个步骤的结果相加。
(3)第三步相加的过程依然是重复前面两步,直到不产生进位为止。
*   测试例子:Add(5,-6)
*   测试输出:-1
*   创    建:2014/4/4
*   扩    展:用来求两个数的减法
************************************************************************/  


int  Add (int  num1,  int  num2)
{
    int sum,carry;
    do
    {
        sum = num1 ^ num2 ;
        carry=  (num1 & num2) << 1 ;
        num1 = sum;
        num2 = carry;
    }while ( num2 != 0 );


    return num1;
}
//递归实现
int Add2(int a,int b)    
{    
    if( b == 0 ) 
return a;//没有进位的时候完成运算     
    int sum,carry;    
    sum = a ^ b;//完成第一步没有进位的加法运算     
    carry=(a & b) << 1;//完成第二步进位并且左移运算     
    return Add(sum,carry);//进行递归,相加     
}  
/*算法思路:
1、从右到左扫描加数,
2若加数的第i位是1,则针对被加数中从第i位到最左边位,
   若第j位是1,则此位置0;否则置1,结束本次循环,即转1。
否则,继续扫描加数的下一位,即转1.
【整个操作可理解为:】从右到左,对加数中的每一个1,对被加数最右端(第0位开始向左)连续的1变0,
      原先被加数中为0的最低位置的那一位变1。  */


int Add3(int a, int b)    
{    
    for( int i = 1; i; i <<= 1 )         
        if( b & i )            
            for(int j = i; j; j <<= 1)        
                if(a & j) 
 a &= ~j;    
                else 
{
a |= j; break;
}                          
    return a ;    

//直接使用加法实现减法
int Minus(int a,int b)    
{    
    int temp = -b;
return Add(a,temp);



/* 思  路:首先取减数的补码,然后相加 */   
int Minus2(int a,int b)    
{    
    for(int i = 1; i && ((b & i) ==0 ); i <<= 1)  
        ;    
    for( i <<= 1; i; i <<=1 )   
        b ^= i;    
    return Add(a,b);    
}    
/* 思  路:
 乘法就是将乘数写成(2^0)*k0 + (2^1)*k1 + (2 ^2)*k2 + ... + (2^31)*k31,其中ki为0或1,
  然后利用位运算和加法就可以了。


*/
int Mul(int a,int b)    
{    
    int ans = 0;    
    for(int i = 1; i; i <<= 1, a <<= 1)    
        if(b & i)    
            ans += a;  //可换成ans= Add( ans,a );   
        return ans;    
}   
/*思  路:
 除法就是由乘法的过程逆推,依次减掉(如果够减的话)divisor << 31、divisor << 30、... 、
 divisor << 2、divisor << 1、divisor(要保证不能溢出)减掉相应数量的除数就在结果加上相应的数量。
*/
int Div(int dividend, int divisor)   
{  
    // assert(divisor != 0)   
    int sign = 1;  
    if(dividend < 0 && divisor > 0 || dividend > 0 && divisor < 0)  
        sign = -1;  
    unsigned int x = (unsigned int)abs(dividend);  
    unsigned int y = (unsigned int)abs(divisor);  
    int bitCnt = sizeof(int) << 3;  
    int quotient = 0;  
    int k = bitCnt-1;  
    while(((1 << k) & y) == 0) k--;  
    for(int j = bitCnt-1-k; j >= 0; j--)  
    {  
        if(x >= (y << j))  
        {  
            x -= (y << j);  
            quotient += (1 << j);  
        }  
    }  
    return sign*quotient;  
}

转载自:http://blog.csdn.net/luckyxiaoqiang/article/details/6886489

0 0
原创粉丝点击