在C语言中不使用除法运算符来对数字进行除法运算

6

在运行时给定分母的情况下,如何在不使用这些运算符('*','/','%')的情况下将一个数字除以一个未知数字。


浮点数还是整数?有符号还是无符号?你卡在哪里了?为什么? - huseyin tugrul buyukisik
展示一些代码并告诉我们你卡在哪里了。这不是一个“帮助你完成作业”的网站。 - Guntram Blohm
如果您被允许在循环控制中使用“-”,那么您应该查看以下链接:http://stackoverflow.com/questions/12697523/performing-bit-division-without-arithmetic-operators/12699549#12699549 - Roger Lindsjö
1
@vinayawsm,您的编辑大幅改变了问题。存在使用加法/减法的答案并不意味着您应该更改问题以允许它们的使用。 - simonc
8个回答

16
void main(){
   int a,b,i=0;
   clrscr();
   printf("Enter the dividend and divisor");
   scanf("%d%d",&a,&b);
   while(a>=b){
      a=a-b;
      i++;
   }

   printf("qoutient is :%d \n remainder : %d",i,a);
   getch();
}

5
尽管代码可以自我说明,但仅包含代码的答案并不能提供足够的信息来被视为高质量。请添加有关您的代码如何解决所提出问题的详细信息。 - user1932079
1
你能不使用循环完成这个任务吗?我在面试中也被问到了同样的问题。当我用这种方法时,面试官告诉我要不用循环来完成。 - AlphaGoku

9
您可以使用这个函数。
int divide(int nu, int de) {

    int temp = 1;
    int quotient = 0;

    while (de <= nu) {
        de <<= 1;
        temp <<= 1;
    }

    //printf("%d %d\n",de,temp,nu);
    while (temp > 1) {
        de >>= 1;
        temp >>= 1;

        if (nu >= de) {
            nu -= de;
            //printf("%d %d\n",quotient,temp);
            quotient += temp;
        }
    }

    return quotient;
}

你可以将分子和分母传递给此函数,并获得所需的商。

3
你正在使用“-”运算符... - V-X
@V-X 抱歉,使用 + 或 - 运算符是可以的。我实际上是在尝试编写不使用 '/' 和 '%' 运算符的代码。 - nomorequestions
你还需要检查参数是负数还是正数。 - alampada

3

最简单的方法:

int divideIntegers(int num, int den){
    int sign = (num*den < 0)? -1 : 1;
    num = abs(num);
    den = abs(den);
    int quo = 0;
    while( (num -= den) >= 0 )
        quo++;
    return sign*quo;
}

1

对于整数除法,您可以使用标准库中的 divldivlldiv 函数:

#include <stdlib.h>
div_t div(int numer, int denom);
ldiv_t ldiv(long int numer, long int denom);
lldiv_t lldiv(long long int numer, long long int denom);

下投票者,能否解释一下你的负评?调用这些函数是否使用了任何被禁止的运算符? - ouah
不是我点踩的,但这个问题没有展示出任何努力。 - LittleBobbyTables - Au Revoir
@LittleBobbyTables 是的,我是在问对我的回答的负评,而不是针对 OP 问题的负评。 - ouah
1
@oauh- 我知道,我只是指出有一种倾向会对低质量/没有努力的问题的答案进行投票,这就是为什么你可能被扣分的原因。 - LittleBobbyTables - Au Revoir

1
下面的方法实现了二进制除法,考虑到两个数字都是正数。如果减法也是一个问题,我们也可以使用二进制操作符来实现。

======

-(int)binaryDivide:(int)numerator with:(int)denominator
{

    if (numerator ==0 || denominator ==1) {
        return numerator;
    }

    if (denominator ==0) {

#ifdef DEBUG
        NSAssert(denominator==0, @"denominator should be greater then 0");
#endif
        return INFINITY;
    }


//    if (numerator <0) {
//        numerator = abs(numerator);
//    }




    int maxBitDenom = [self getMaxBit:denominator];
    int maxBitNumerator = [self getMaxBit:numerator];
    int msbNumber = [self getMSB:maxBitDenom ofNumber:numerator];

    int qoutient = 0;

    int subResult = 0;

    int remainingBits = maxBitNumerator-maxBitDenom;


    if(msbNumber>=denominator){
        qoutient |=1;
        subResult = msbNumber- denominator;
    }
    else{
        subResult = msbNumber;
    }


    while(remainingBits>0){
        int msbBit = (numerator & (1<<(remainingBits-1)))>0?1:0;
        subResult = (subResult <<1) |msbBit;
        if(subResult >= denominator){
            subResult = subResult-denominator;
            qoutient= (qoutient<<1)|1;
        }
        else{
            qoutient = qoutient<<1;
        }
        remainingBits--;

    }
    return qoutient;
}

-(int)getMaxBit:(int)inputNumber
{
    int maxBit =0;
    BOOL isMaxBitSet = NO;
    for(int i=0;i<sizeof(inputNumber)*8;i++){
        if( inputNumber & (1<<i) ){
            maxBit = i;
            isMaxBitSet=YES;
        }
    }
    if (isMaxBitSet) {
        maxBit+=1;
    }
    return maxBit;
}



-(int)getMSB:(int)bits ofNumber:(int)number
{
    int numbeMaxBit = [self getMaxBit:number];
    return number>>(numbeMaxBit -bits);
}

0

Python中用于常数除法的伪代码

n_bits = 输入位数,期望在此范围内进行准确的除法运算

den = 除数

prec = int(math.ceil(math.log(den,2)))
shift = n_bits + prec
mult = int(math.ceil((1<<shift)/float(den)))
answer = (x*mult) >> shift
err = sum([round(x/den) - ((x*mult) >> shift) for x in range(1<<n_bits)])

乘法可以通过移位和加法实现


0

你的问题非常模糊,但是我可以举一个把数字除以2的具体案例。可以通过位移操作将数字向右移动一位来完成。这是强度降低优化的一种形式。

例如,二进制中的1101000(十进制数104),向右移动一位变成0110100(十进制数52):最低位的1被删除。同样,通过任何2的幂次方(2 pow k)进行的除法都可以通过右移k个位置来完成。因为位移操作通常比除法操作更快速。

测试代码如下:

#include <stdio.h>

main()
{
   int i = 104; 
   int k = 3; //
   int j = i >> k ; //==>  i / 2 pow k 
  printf("j = %d \n",j);
}

0

这是解决问题的一种非常简单的方法;使用循环和基本的[+-]运算符。

如果您需要十进制的答案,可以使用times_ten和divide_by_ten函数。在这种情况下,您应该查看atoi()函数; times_ten将从char数组中提取整数,在转换回整数之前在末尾添加一个'0'。 divide_by_ten将存储整数的最后一个字符,将此字符与'.'相减,并在将存储的最后一个数字添加回数组之前将其添加到数组中,然后将其转换回整数。Atoi()将根据我们在char数组中操作的小数四舍五入整数。

这是仅支持整数结果的版本,其中有一个额外的函数(leftover_division())替换了“%”运算符。 [b]将指向整数的指针传递给divide_rounded()函数,而不是常规整数,并调整divide_rounded()中'a'的值,应该使剩余函数变得多余,如果您需要知道剩余部分,则可以节省大量计算时间。[/b]

#include <stdio.h>
#include <stdlib.h>



int divide_rounded(int a, int b){
   int outcome_rounded = 0;
   while(a > b){
      a = a - b;
      outcome_rounded ++;
   }
   return outcome_rounded;
}

int leftover_division(int a, int b){
   while (a >= b){
      a = a - b;
   }
   return a;//this will return remainder

}

main(){
   int number = 20;
   int divisor = 3;
   int outcome;
   int leftover;

   outcome = divide_rounded(number, divisor);
   leftover = leftover_division(number, divisor);

   printf("[%d] divided by [%d] = [%d] + [%d]\n", number, divisor, outcome, leftover);

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接