不使用除法实现除法运算 和模运算

代码如下。包含测试代码

原理就是:枚举二进制余数中1的位置 +二分搜索。O(32*32) 

不过此算法可以加上两重的二分搜索。时间复杂度会更优。

#include <stdio.h>
#include 
<stdlib.h>
#include 
<iostream>
#include 
<vector>
#include 
<map>
#include 
<string>
#include 
<time.h>
using namespace std;
void module(int a ,int b ,int *c,int*d)
{
    
if (a < b)
    {
        
*= 0;
        
*d  = a;
        
return ;
    }
    unsigned 
int k = 0;
    
int t  = 32;
    
for (  int j = 0; j< t;j++)
    {
        
int d = (a - b*(k+(1<<j)));
        
if ( d < 0)
        {
            
if (j ==0)
            {
                
break;
            }
            k 
= k+(1<<(j-1));
            t 
= j;
            j 
= -1;//j++
        }
        
if (d == 0)
        {
            k 
= k+(1<<j);
            
break;
        }     
    }
    
*= k;
    
*= a-b*k;
}
void main()
{
    
    
int i = 10000;
    
while(i--)
    {
        srand(time(NULL));
        
//int a = rand(),b = rand();
        int a = 1,b = 1;
        
int c,d;
        
        module(a,b,
&c,&d);
        
        
if (c!=a/|| d !=a%b )
        {
            printf(
"%d %d  %d %d %d %d\n",a,b,c,d,a/b,a%b);
        }
        
//printf("finished % d\n",i );
    }
    printf(
"finished\n" );
}

 另附上同样解法的简洁的代码

int div1(const int x, const int y) {
    
int left_num = x;
    
int result = 0;
    
while (left_num >= y) {
        
int multi = 1;
        
while (y * multi <= (left_num >> 1)) 
        {
            multi 
= multi << 1;
        }
        result 
=result +multi;
        left_num 
= left_num - y*multi;
    }
    
return result;
}
//优化
int div2(const int x, const int y) {
    unsigned 
int left_num = x;
    
int result = 0;
    unsigned 
int t = 0x80000000;
    
int move = 0;
    
while(t)
    {
        
if(t<=left_num)
        {
            result 
= result+t;
            left_num 
= left_num - t;
        }
        t 
= t>>1;
    }
    
return result;
}

 

 

 

posted @ 2010-08-11 11:48  David Luo  阅读(962)  评论(0编辑  收藏  举报