【问题标题】:Division without using '/' operator [closed]不使用“/”运算符的除法[关闭]
【发布时间】:2017-05-08 18:13:26
【问题描述】:

我不能使用“/”和循环,我必须除一些数字。 操作数是 32 位的,我不能使用递归。

我想过使用 shr 但它只给我 2^n divison 并且它也不会保存提醒。

有什么想法吗?

【问题讨论】:

  • 除法只是重复减法。为什么不能使用除法运算符?
  • @Domi 任何解决方法都可能比常规除法运算符占用更多内存??!
  • @AlexG 那是肯定的......听起来像是一个虚构的要求或借口......
  • 除数是编译时已知的常数吗?
  • @Dorni:在这种情况下,您可以只使用magic number method,它只需要乘法、加法和移位。请点击edit 按钮并将来自 cmets 的所有相关信息添加到您的问题中,因为人们对其含糊不清感到沮丧。

标签: c++ c math division divide


【解决方案1】:
#include <stdio.h>
#include <stdlib.h>

int main()
{
   div_t output;

   output = div(27, 4);
   printf("Quotient part of (27/ 4) = %d\n", output.quot);
   printf("Remainder part of (27/4) = %d\n", output.rem);

   output = div(27, 3);
   printf("Quotient part of (27/ 3) = %d\n", output.quot);
   printf("Remainder part of (27/3) = %d\n", output.rem);

   return(0);
}

输出:

Quotient part of (27/ 4) = 6
Remainder part of (27/4) = 3
Quotient part of (27/ 3) = 9
Remainder part of (27/3) = 0

【讨论】:

    【解决方案2】:

    根据幻数试试这个方法:
    我基于这个link实现了它
    它只对固定除数有用。

    #include <iostream>
    #include <cmath>
    using namespace std;
    
    int main() {
        // your code goes here
    
        unsigned long MAX_NUM=1<<30; //Max num = 1073741824
    
        unsigned long num = 1073741824;
        unsigned long divisor=17;
    
        //unsigned long magic_num=round(double(MAX_NUM)/divisor);
        unsigned long magic_num = 63161284 // Fixed for divisor = 17
    
        unsigned long div = (num * magic_num) >> 30;
        unsigned long remain = num - div * divisor;
    
        cout << div << endl;
        cout << remain << endl;
    
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      如果这是一项学术练习,他们可能希望你这样做:

      a/b ::== e**(log(a) - log(b))

      【讨论】:

      • OP 声称这是针对资源受限的系统,显然,所以我想超越函数可能会被禁止使用。
      • 他还想要剩下的。但我宁愿用这种不符合的要求来结束这个问题。
      • 看来我们现在在这里变得不可能了。
      【解决方案4】:
      int a_div_b( int a, int b, int pow=0 ) {
        if (a<b) return 0;
        if (a < (b<<(pow+1)))
          return a_div_b(a-(b<<pow), b) + (1<<pow);
        return a_div_b(a, b, pow+1);
      }
      

      没有循环,没有/O((log(a/b))^2) 时间。我可能会提高到O(log(a/b)),但我很懒(一旦找到它,就从最大 pow 递归 down,而不是备份)。

      可以通过b-a_div_b(a,b)*a 轻松计算余数,而无需使用循环或/

      它应该使用 O(1) 内存,因为它是尾端递归的。

      【讨论】:

      • 很好的答案,但 OP 在 cmets 中说:“递归不在讨论范围内”,我认为这意味着“不允许递归”。
      • @PaulR 我很高兴 OP 有不同的问题。他可以按“”按钮询问。
      • 是的,球门柱在这个问题上进展得非常快!
      • 我会说只是将其展开为 32 位无符号值。
      • @Dorni 不,这使用 O(1) 内存,假设您的编译器没有脑死亡;它是尾递归的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-08
      • 2010-09-21
      相关资源
      最近更新 更多