不使用 '/' 进行除法

发布于 2024-10-24 13:06:00 字数 221 浏览 3 评论 0原文

谁能告诉我一种在不使用“/”的情况下执行除法运算的有效方法。我可以使用类似于二分搜索的方法以 log(n) 步计算整数值。

115/3 
57 * 3 > 115
28 * 3 < 115
47 * 3 > 115
.
.
.
38 * 3 is quotient value .....

但还有其他更有效的方法吗?

Can anyone tell me an efficient approach to perform the division operation without using '/'. I can calculate the integer value in log(n) steps using a method similar to binary search.

115/3 
57 * 3 > 115
28 * 3 < 115
47 * 3 > 115
.
.
.
38 * 3 is quotient value .....

But is there any other more efficient method?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

何其悲哀 2024-10-31 13:06:00

典型的方法是移位和减法。这基本上与我们在学校学到的长除法非常相似。最大的区别在于,在小数除法中,您需要估计结果的下一位。在二进制中,这是微不足道的。下一位始终为 0 或 1。如果(左移)除数小于或等于当前被除数值,则将其相减,结果的当前位为 1。如果它更大,则结果的当前位是 0。代码如下所示:

unsigned divide(unsigned dividend, unsigned divisor) { 

    unsigned denom=divisor;
    unsigned current = 1;
    unsigned answer=0;

    if ( denom > dividend) 
        return 0;

    if ( denom == dividend)
        return 1;

    while (denom <= dividend) {
        denom <<= 1;
        current <<= 1;
    }

    denom >>= 1;
    current >>= 1;

    while (current!=0) {
        if ( dividend >= denom) {
            dividend -= denom;
            answer |= current;
        }
        current >>= 1;
        denom >>= 1;
    }    
    return answer;
}

这与我们手动进行长除法时非常相似。例如,我们考虑 972/5。在十进制长除法中,我们这样做:

 ____ 
5)972

然后我们单独计算每个数字。 5 会变成 9 一次,所以我们在答案的该数字中记下 1,并从被除数(该数字)中减去 1*5,然后“减去”被除数的下一位:

  1
 ----
5)972
  5
  ---
  47

我们继续做同样的事情直到我们填完所有数字:

   194
  ----
 5)972
   5
   ---
   47
   45
   ---
    22
    20
   ---
     2

所以,我们的答案是 194 余数 2。

现在让我们考虑同样的事情,但是是二进制的。 972 二进制为 11 1100 1100,5 为 101。现在,二进制与十进制除法之间存在一个根本区别:在十进制中,特定数字可以是 0 到 9 之间的任何数字,因此我们必须进行乘法才能找到要从被除数中减去的中间结果。在二进制中,数字只会是 0 或 1。我们永远不需要相乘,因为我们只会乘以 0 或 1(我们通常在 if 语句中处理 - 要么我们相减,要么不相乘) )。

   -----------
101)1111001100

因此,我们的第一步是找出结果中的第一个数字。我们通过比较 101 和 1111001100 并将其左移直到它更大来实现这一点。这给了我们:

  |
 1111001100
10100000000

当我们进行移位时,我们会计算移位的位置数,这样我们就知道在任何给定时间我们要填写结果的哪一位。我已经用上面的垂直条展示了这一点。然后,我们将中间结果右移一位,并将竖线随之右移,以表示我们要在哪里填充结果数字:

    |
  1111001100
  1010000000

从那里我们检查移动后的除数是否小于被除数。如果是,我们在答案中的适当位置填写 1,并从中间结果中减去移位除数[为了帮助保持列笔直,我将插入一些空格]:

            1  
     -----------------------------
  101)1  1  1  1  0  0  1  1  0  0
      1  0  1  0  0  0  0  0  0  0
      ----------------------------
         1  0  1

我们继续以同样的方式,填充结果的数字,并从中间结果中减去移位除数,直到填充完所有数字。为了进一步让事情变得简单,我将在减数旁边最右边写下结果的每个数字:

            1  1  0  0  0  0  1  0
     -----------------------------
  101)1  1  1  1  0  0  1  1  0  0
      1  0  1                             1
      -----------------------------
         1  0  1
         1  0  1                           1
      -----------------------------
            0  0  0                          0
         --------------------------
               0  0  0                        0
          -------------------------
                  0  0  1                      0
          -------------------------
                     0  1  1                    0
          -------------------------
                        1  1  0   
                        1  0  1                   1
           ------------------------
                           0  1  0                 0

因此,我们得到的结果是 11000010,余数 10。将它们转换为十进制,我们得到预期分别为 194 和 2。

让我们考虑一下这与上面的代码有何关系。我们首先将除数左移,直到它大于被除数。然后,我们反复将其右移,并为每次右移检查该值是否小于上次减法后得到的中间值。如果小于,我们再次减去并在结果中为该数字填充 1。如果它更大,我们“减去 0”(不做任何事情)并在结果中为该数字填充“0”(这也不需要我们做任何事情,因为这些数字已经设置为0 的)。

当我们填完所有数字后,这就是我们的结果,而我们尚未减去的任何金额就是我们的余数。

有人问我为什么在代码中使用|=而不是+=。我希望这有助于解释原因。尽管在这种情况下它们产生相同的结果,但我不考虑将每个数字添加到现有的部分答案中。相反,我认为答案中的那个位置是空的,只是填充它。

The typical way is to shift and subtract. This is basically pretty similar to long division as we learned it in school. The big difference is that in decimal division you need to estimate the next digit of the result. In binary, that's trivial. The next digit is always either 0 or 1. If the (left-shifted) divisor is less than or equal to the current dividend value, you subtract it, and the current bit of the result is a 1. If it's greater, then the current bit of the result is a 0. Code looks like this:

unsigned divide(unsigned dividend, unsigned divisor) { 

    unsigned denom=divisor;
    unsigned current = 1;
    unsigned answer=0;

    if ( denom > dividend) 
        return 0;

    if ( denom == dividend)
        return 1;

    while (denom <= dividend) {
        denom <<= 1;
        current <<= 1;
    }

    denom >>= 1;
    current >>= 1;

    while (current!=0) {
        if ( dividend >= denom) {
            dividend -= denom;
            answer |= current;
        }
        current >>= 1;
        denom >>= 1;
    }    
    return answer;
}

This works pretty much like when we do long division by hand. For example, let's consider 972/5. In decimal long division, we do something like this:

 ____ 
5)972

Then we figure each digit individually. 5 goes into 9 once, so we write down a 1 in that digit of the answer, and subtract 1*5 from (that digit) of the dividend, then "bring down" the next digit of the dividend:

  1
 ----
5)972
  5
  ---
  47

We continue doing the same until we've filled in all the digits:

   194
  ----
 5)972
   5
   ---
   47
   45
   ---
    22
    20
   ---
     2

So, our answer is 194 remainder 2.

Now let's consider the same thing, but in binary. 972 in binary is 11 1100 1100, and 5 is 101. Now there is one fundamental difference between doing the division in binary vs. decimal: in decimal a particular digit could be anything from 0 to 9, so we had to multiply to find the intermediate result we were going to subtract from the dividend. In binary the digit is only ever going to be a 0 or a 1. We never need to multiply because we would only ever multiply by 0 or 1 (which we normally handle in an if statement--either we subtract or we don't).

   -----------
101)1111001100

So, our first step is to figure out which will be the first digit in the result. We do that by comparing 101 to 1111001100, and shifting it left until it's greater. That gives us:

  |
 1111001100
10100000000

As we do that shifting, we count the number of places we've shifted so we know which digit of the result we're filling in at any given time. I've shown that with the vertical bar above. Then we shift the intermediate result right one place, and shift the vertical bar right with it to signify where we're doing to fill in a result digit:

    |
  1111001100
  1010000000

From there we check if the shifted divisor is less than the dividend. If it is, we fill in a 1 in the proper place in the answer, and subtract the shifted divisor from the intermediate result [and to help keep columns straight, I'm going to insert some spaces]:

            1  
     -----------------------------
  101)1  1  1  1  0  0  1  1  0  0
      1  0  1  0  0  0  0  0  0  0
      ----------------------------
         1  0  1

We continue the same way, filling in digits of the result, and subtracting the shifted divisor from the intermediate result until we've filled in all the digits. In a further attempt at helping keep things straight, I'm going to write in each digit of the result at the far right next to the subtrahend:

            1  1  0  0  0  0  1  0
     -----------------------------
  101)1  1  1  1  0  0  1  1  0  0
      1  0  1                             1
      -----------------------------
         1  0  1
         1  0  1                           1
      -----------------------------
            0  0  0                          0
         --------------------------
               0  0  0                        0
          -------------------------
                  0  0  1                      0
          -------------------------
                     0  1  1                    0
          -------------------------
                        1  1  0   
                        1  0  1                   1
           ------------------------
                           0  1  0                 0

So, we get a result of 11000010, remainder 10. Converting those to decimal, we get the expected 194 and 2 respectively.

Let's consider how that relates to the code above. We start by shifting the divisor left until it's greater than the dividend. We then repeatedly shift it right and for each right shift check whether that value is less than the intermediate we got after the last subtraction. If it's less, we subtract again and fill in a 1 for that digit in our result. If it's greater, we "subtract 0" (don't do anything) and fill in a '0' for that digit in the result (which, again, doesn't require us to do anything, since those digits are already set to 0's).

When we've filled in all the digits, that's our result, and any amount left that we haven't subtracted yet is our remainder.

Some have asked why I used |= instead of += in the code. I hope this helps explain why. Although in this case they produce the same result, I don't think of adding each digit to the existing partial answer. Rather, I think of it that spot in the answer as being empty, and the or just fills it in.

绅刃 2024-10-31 13:06:00

选项

  • 根据您在小学学到的长除法算法编写您自己的除法算法。
  • 取分母的 -1 次方,
  • 乘以分子 取分子和分母的对数,减去,然后将对数的底数提高到相同的次方

Options:

  • Code your own division algorithm based on the long division algorithm you learned in grade school.
  • Take the -1 power of the denominator, and multiply onto the numerator
  • Take the logs of the numerator and denominator, subtract, and then raise the base of the log to that same power
要走就滚别墨迹 2024-10-31 13:06:00

使用基本的高中数学进行简单的 Python 实现。分母只是一个负 1 次方的数字。

def divide(a, b):
    return a * b ** -1

Simple Python implementation using basic high school math. A denominator is simply a number to the power of negative 1.

def divide(a, b):
    return a * b ** -1
荒路情人 2024-10-31 13:06:00

以下是不使用除法运算符对数字进行除法的 Java 代码。

private static int binaryDivide(int dividend, int divisor) {
    int current = 1;
    int denom = divisor;
    // This step is required to find the biggest current number which can be
    // divided with the number safely.
    while (denom <= dividend) {
        current <<= 1;
        denom <<= 1;
    }
    // Since we may have increased the denomitor more than dividend
    // thus we need to go back one shift, and same would apply for current.
    denom >>= 1;
    current >>= 1;
    int answer = 0;
    // Now deal with the smaller number.
    while (current != 0) {
        if (dividend >= denom) {
            dividend -= denom;
            answer |= current;
        }
        current >>= 1;
        denom >>= 1;
    }
    return answer;
}

Following is the Java code for dividing number without using division operator.

private static int binaryDivide(int dividend, int divisor) {
    int current = 1;
    int denom = divisor;
    // This step is required to find the biggest current number which can be
    // divided with the number safely.
    while (denom <= dividend) {
        current <<= 1;
        denom <<= 1;
    }
    // Since we may have increased the denomitor more than dividend
    // thus we need to go back one shift, and same would apply for current.
    denom >>= 1;
    current >>= 1;
    int answer = 0;
    // Now deal with the smaller number.
    while (current != 0) {
        if (dividend >= denom) {
            dividend -= denom;
            answer |= current;
        }
        current >>= 1;
        denom >>= 1;
    }
    return answer;
}
无戏配角 2024-10-31 13:06:00

这是针对不允许使用乘法的问题的解决方案)。

我喜欢这个解决方案:https://stackoverflow.com/a/5387432/1008519,但我发现有点困难原因(尤其是 | 部分)。这个解决方案在我看来更有意义:

var divide = function (dividend, divisor) {
  // Handle 0 divisor
  if (divisor === 0) {
    return NaN;
  }

  // Handle negative numbers
  var isNegative = false;
  if (dividend < 0) {
    // Change sign
    dividend = ~dividend+1;
    isNegative = !isNegative;
  }

  if (divisor < 0) {
    // Change sign
    divisor = ~divisor+1;
    isNegative = !isNegative;
  }

  /**
   * Main algorithm
   */

  var result = 1;
  var denominator = divisor;
  // Double denominator value with bitwise shift until bigger than dividend
  while (dividend > denominator) {
    denominator <<= 1;
    result <<= 1;
  }

  // Subtract divisor value until denominator is smaller than dividend
  while (denominator > dividend) {
    denominator -= divisor;
    result -= 1;
  }

  // If one of dividend or divisor was negative, change sign of result
  if (isNegative) {
    result = ~result+1;
  }

  return result;
}
  1. 将结果初始化为 1(因为我们要将分母加倍,直到它大于被除数)
  2. 将分母加倍(按位移位)直到它大于被除数
  3. 因为我们知道我们的分母大于我们的被除数,我们可以减去除数,直到它小于被除数
  4. 返回记录的使用除数尽可能接近分母的操作

以下是一些测试运行:

console.log(divide(-16, 3)); // -5
console.log(divide(16, 3)); // 5
console.log(divide(16, 33)); // 0
console.log(divide(16, 0)); // NaN
console.log(divide(384, 15)); // 25

这是一个要点处理除数为 0 的情况以及负除数和/或除数: https://gist.github.com/mlunoe /e34f14cff4d5c57dd90a5626266c4130

(This is a solution to the problem where you are not allowed to use multiplication either).

I like this solution: https://stackoverflow.com/a/5387432/1008519, but I find it somewhat hard to reason about (especially the |-part). This solution makes a little more sense in my head:

var divide = function (dividend, divisor) {
  // Handle 0 divisor
  if (divisor === 0) {
    return NaN;
  }

  // Handle negative numbers
  var isNegative = false;
  if (dividend < 0) {
    // Change sign
    dividend = ~dividend+1;
    isNegative = !isNegative;
  }

  if (divisor < 0) {
    // Change sign
    divisor = ~divisor+1;
    isNegative = !isNegative;
  }

  /**
   * Main algorithm
   */

  var result = 1;
  var denominator = divisor;
  // Double denominator value with bitwise shift until bigger than dividend
  while (dividend > denominator) {
    denominator <<= 1;
    result <<= 1;
  }

  // Subtract divisor value until denominator is smaller than dividend
  while (denominator > dividend) {
    denominator -= divisor;
    result -= 1;
  }

  // If one of dividend or divisor was negative, change sign of result
  if (isNegative) {
    result = ~result+1;
  }

  return result;
}
  1. Initialize the result to 1 (since we are going to double our denominator until it is bigger than the dividend)
  2. Double the denominator (with bitwise shifts) until it is bigger than the dividend
  3. Since we know our denominator is bigger than our dividend, we can subtract the divisor until it is less than the dividend
  4. Return the recorded actions it took to get as close to the denominator as possible using the divisor

Here are some test runs:

console.log(divide(-16, 3)); // -5
console.log(divide(16, 3)); // 5
console.log(divide(16, 33)); // 0
console.log(divide(16, 0)); // NaN
console.log(divide(384, 15)); // 25

Here is a gist handling both the 0 divisor case and negative dividend and/or divisor: https://gist.github.com/mlunoe/e34f14cff4d5c57dd90a5626266c4130

许仙没带伞 2024-10-31 13:06:00

既然OP说这是一个面试问题,我认为面试官除了看你的编码能力之外还想看以下的东西。 (假设您使用的是Java)

  1. 如何处理负数?将被除数和除数都转换为正数是很常见的。但是,您可能会忘记 Math.abs(Integer.MIN_VALUE) 仍然是 Integer.MIN_VALUE。因此,当被除数为Integer.MIN_VALUE时,应单独计算。

  2. “Integer.MIN_VALUE/-1”的结果是什么? Integer 中没有这样的值。你应该和面试官讨论一下。您可以针对这种情况引发异常。

这是这个问题的Java代码,您可以验证它leetcode:除两个整数

public int divide(int dividend, int divisor) {

    if(divisor == 0)
        throw new Exception("Zero as divisor!");

    int a = Math.abs(dividend);
    int b = Math.abs(divisor);

    boolean isPos = true;
    if(dividend < 0) isPos = !isPos;
    if(divisor < 0) isPos = !isPos;

    if(divisor == Integer.MIN_VALUE){

        if(dividend == Integer.MIN_VALUE) return 1;
        else return 0;
    }

    if(dividend == Integer.MIN_VALUE) {

        if(divisor == -1){

            // the result is out of Integer's range.
            throw new Exception("Invalid result.");
        } else {
            // Because Math.abs(Integer.MIN_VALUE) = Integer.MIN_VALUE
            // we avoid it by adding a positive divisor to Integer.MIN_VALUE
            // here I combined two cases: divisor > 0 and divisor < 0
            return divide((dividend + b), divisor) - divisor/b;
        }
    }

    int res = 0;        
    int product = b;

    while(a >= b){

        int multiplier = 1;
        while(a - product >= product){

            product = product << 1;// "product << 1" is actually "product * 2"
            multiplier = multiplier << 1;
        }
        res += multiplier;
        a -= product;
        product = b;
    }

    return isPos?res:-res;

}

Since the OP said it's an interview question, I think the interviewer wants to see the following things in addition to your coding skills. (Suppose you are using Java)

  1. How to deal with negative numbers? It's common to convert both the dividend and the divisor to positive numbers. However, you may forget that Math.abs(Integer.MIN_VALUE) is still Integer.MIN_VALUE. Therefore, when the dividend is Integer.MIN_VALUE, you should calculate it separately.

  2. What's the result of "Integer.MIN_VALUE/-1"? There is no such value in Integer. You should discuss it with the interviewer. You can throw an exception for this condition.

Here is the Java code for this question and you can validate it leetcode:divide two integers:

public int divide(int dividend, int divisor) {

    if(divisor == 0)
        throw new Exception("Zero as divisor!");

    int a = Math.abs(dividend);
    int b = Math.abs(divisor);

    boolean isPos = true;
    if(dividend < 0) isPos = !isPos;
    if(divisor < 0) isPos = !isPos;

    if(divisor == Integer.MIN_VALUE){

        if(dividend == Integer.MIN_VALUE) return 1;
        else return 0;
    }

    if(dividend == Integer.MIN_VALUE) {

        if(divisor == -1){

            // the result is out of Integer's range.
            throw new Exception("Invalid result.");
        } else {
            // Because Math.abs(Integer.MIN_VALUE) = Integer.MIN_VALUE
            // we avoid it by adding a positive divisor to Integer.MIN_VALUE
            // here I combined two cases: divisor > 0 and divisor < 0
            return divide((dividend + b), divisor) - divisor/b;
        }
    }

    int res = 0;        
    int product = b;

    while(a >= b){

        int multiplier = 1;
        while(a - product >= product){

            product = product << 1;// "product << 1" is actually "product * 2"
            multiplier = multiplier << 1;
        }
        res += multiplier;
        a -= product;
        product = b;
    }

    return isPos?res:-res;

}
不知所踪 2024-10-31 13:06:00

主要概念:

假设我们计算20/4,所以

4*(1+1) = 8 *(1+1) = 16 *(1+1) == 32 (which is bigger) X
so go back to 16 and try 16*(1+0.5) == 24 (bigger) X
so go back to 16 and try 16*(1+0.25) == 20 

代码:

float product=1,multiplier=2,a=1;
int steps=0;

void divCore(float number, float divideBy,float lastDivison)
{
    steps++;
    //epsilon check e.g (10/3) will never ends
    if(number - divideBy < 0.01)
        return;
    else
    {
        lastDivison = divideBy; 
        divideBy *= multiplier;
        if(number >= divideBy)
        {
            product *= multiplier;
            divCore(number,divideBy,lastDivison);
        }
        else
        {
            a *= 0.5;
            multiplier = 1 + a;
            divCore(number,lastDivison,lastDivison);
        }
    }
}

float Divide(float numerator, float denominator)
{
    //init data
    int neg=(numerator<0)?-1:1;
    neg*=(denominator<0)?-1:1;
    product = 1;
    multiplier = 2;
    a = 1;
    steps =0;
    divCore(abs(numerator),abs(denominator),0);
    return product*neg;
}

The main concept :

Let's say we are calc 20/4, so

4*(1+1) = 8 *(1+1) = 16 *(1+1) == 32 (which is bigger) X
so go back to 16 and try 16*(1+0.5) == 24 (bigger) X
so go back to 16 and try 16*(1+0.25) == 20 

The code:

float product=1,multiplier=2,a=1;
int steps=0;

void divCore(float number, float divideBy,float lastDivison)
{
    steps++;
    //epsilon check e.g (10/3) will never ends
    if(number - divideBy < 0.01)
        return;
    else
    {
        lastDivison = divideBy; 
        divideBy *= multiplier;
        if(number >= divideBy)
        {
            product *= multiplier;
            divCore(number,divideBy,lastDivison);
        }
        else
        {
            a *= 0.5;
            multiplier = 1 + a;
            divCore(number,lastDivison,lastDivison);
        }
    }
}

float Divide(float numerator, float denominator)
{
    //init data
    int neg=(numerator<0)?-1:1;
    neg*=(denominator<0)?-1:1;
    product = 1;
    multiplier = 2;
    a = 1;
    steps =0;
    divCore(abs(numerator),abs(denominator),0);
    return product*neg;
}
混吃等死 2024-10-31 13:06:00

不使用 / 进行两个数字相除

int div(int a,int b){

    if(b == 0)
         return -1;   //undefined
    else if (b == 1)
         return a;    
    else if(b > 1){

       int count = 0;
       for(int i=b;i<=a;i+=b){
           count++;
       }
    }

    return count;

}

Division of two numbers without using /

int div(int a,int b){

    if(b == 0)
         return -1;   //undefined
    else if (b == 1)
         return a;    
    else if(b > 1){

       int count = 0;
       for(int i=b;i<=a;i+=b){
           count++;
       }
    }

    return count;

}
巴黎盛开的樱花 2024-10-31 13:06:00

这是一个不使用“/”运算符的简单整数除法:-

public static int divide(int numerator, int denominator) throws Exception {

    int q = 0;
    boolean isNumPos = (numerator >= 0) ? true : false;
    boolean isDenPos = (denominator >= 0) ? true : false;

    if (denominator == 0) throw new Exception("Divide by 0: not an integer result");

    numerator = Math.abs(numerator);
    denominator = Math.abs(denominator);

    while (denominator <= numerator) {
        numerator -= denominator;
        q++;
    }

    return (isNumPos ^ isDenPos) ? -q : q;
}

Here is a simple divide method for ints without using a '/' operator:-

public static int divide(int numerator, int denominator) throws Exception {

    int q = 0;
    boolean isNumPos = (numerator >= 0) ? true : false;
    boolean isDenPos = (denominator >= 0) ? true : false;

    if (denominator == 0) throw new Exception("Divide by 0: not an integer result");

    numerator = Math.abs(numerator);
    denominator = Math.abs(denominator);

    while (denominator <= numerator) {
        numerator -= denominator;
        q++;
    }

    return (isNumPos ^ isDenPos) ? -q : q;
}
探春 2024-10-31 13:06:00

这是 JavaScript 中的一个:

function divideWithoutDivision(a, b, precision) {
    precision = precision > 0 ? precision : 10

    var result = 0
    var decimalPosition = 1
    var A = a*0.1
    var howManyTimes = 0

    while (precision--) {
        A = A * 10
        howManyTimes = 0

        while (A >= b) {
            A = A - b
            howManyTimes += 1
        }

        result = result + howManyTimes*decimalPosition
        decimalPosition = decimalPosition * 0.1
    }

    return result
}

document.write('<br>20/3 = ', divideWithoutDivision(20, 3))
document.write('<br>10/3 = ', divideWithoutDivision(10, 3))
document.write('<br>10/4 = ', divideWithoutDivision(10, 4))
document.write('<br>17/14 = ', divideWithoutDivision(17, 14))
document.write('<br>23/4 = ', divideWithoutDivision(23, 4))

可以通过在精度的最后一位小数后四舍五入来进一步改进。

Here's one in JavaScript:

function divideWithoutDivision(a, b, precision) {
    precision = precision > 0 ? precision : 10

    var result = 0
    var decimalPosition = 1
    var A = a*0.1
    var howManyTimes = 0

    while (precision--) {
        A = A * 10
        howManyTimes = 0

        while (A >= b) {
            A = A - b
            howManyTimes += 1
        }

        result = result + howManyTimes*decimalPosition
        decimalPosition = decimalPosition * 0.1
    }

    return result
}

document.write('<br>20/3 = ', divideWithoutDivision(20, 3))
document.write('<br>10/3 = ', divideWithoutDivision(10, 3))
document.write('<br>10/4 = ', divideWithoutDivision(10, 4))
document.write('<br>17/14 = ', divideWithoutDivision(17, 14))
document.write('<br>23/4 = ', divideWithoutDivision(23, 4))

It could be further improved by rounding after the last decimal place of the precision.

陪你到最终 2024-10-31 13:06:00

也许您可以设计一种使用>>序列来做到这一点的方法。 (位移位)与其他按位运算符。 维基百科:按位运算符文章中有一个伪代码示例。

Perhaps you can devise a way to do it using sequences of >> (bit shifts) with other bitwise operators. There's an example in psuedo-code in the Wikipedia: Bitwise Operator article.

澜川若宁 2024-10-31 13:06:00

好吧,如果这只是整数/整数 = int 类型除法,那么很容易得到 x / n = int.dec 的整数部分,方法是添加 n+n+n+n 直到 n 大于 x,然后从你的数。

要在不使用 *、/、% 或其他数学函数的情况下获得 int/int = real,您可以执行以下操作。例如,您可以将余数作为有理数返回。这样做的优点是准确。您还可以使用字符串修改将 r 转换为 r0...(您选择精度),然后重复相同的加法技巧,然后连接结果。

当然,您可以尝试享受位移位的乐趣。

我不知道这是否是一个“愚蠢的把戏”,因为它是对你如何使用简单的东西(加法、减法)来构建复杂的东西(除法)的测试。这是您的潜在雇主可能需要的一项技能,因为没有一个操作员可以处理所有事情。像这样的问题(理论上)应该把不能设计算法的人从能设计算法的人中淘汰掉。

我确实认为答案在互联网上如此容易获得是一个问题,但这是一个实施问题。

Well, if this is only integer/integer = int type division, it's pretty easy to get the integer part of x / n = int.dec by adding n+n+n+n until n is greater than x, then subtracting one from your 'n' count.

To get int/int = real without using *, /, %, or other math functions, you could do several things. You could return the remainder as a rational, for example. That has the advantage of being exact. You could also use string modification to turn your r into r0... (you pick the precision) and then repeat the same addition trick, then concatenate the results.

And of course, you could try having fun with bit shifting.

I don't know if this is so much a 'silly trick' as it is a test of how well you can use simple things (addition, subtraction) to build a complex thing (division). This is a skill that your potential employer might need, because there isn't an operator for everything. A question like this should (theoretically) weed out people who can't design algorithms from people who can.

I do think it's a problem that the answer is so readily available on the internet, but that's an implementation issue.

我恋#小黄人 2024-10-31 13:06:00

这是解决我的问题的函数:

func printRemainderAndQuotient(numerator: Int,divisor: Int) {
  var multiplier = 0
  var differene = numerator - divisor
  var dynamicNumber = 0
  if divisor == 0 {
    print("invalid divisor")
    return
  }
  if divisor == numerator {
    print("quotient : " + "1")
    print("remainder : " + "0")
    return
  }
  while differene >= divisor {
    multiplier = multiplier + 1
    dynamicNumber = divisor * multiplier
    differene = numerator - dynamicNumber
  }
  print("quotient : " + "\(multiplier)")
  print("remainder : " + "\(differene)")
}

This is the function that solved my problem:

func printRemainderAndQuotient(numerator: Int,divisor: Int) {
  var multiplier = 0
  var differene = numerator - divisor
  var dynamicNumber = 0
  if divisor == 0 {
    print("invalid divisor")
    return
  }
  if divisor == numerator {
    print("quotient : " + "1")
    print("remainder : " + "0")
    return
  }
  while differene >= divisor {
    multiplier = multiplier + 1
    dynamicNumber = divisor * multiplier
    differene = numerator - dynamicNumber
  }
  print("quotient : " + "\(multiplier)")
  print("remainder : " + "\(differene)")
}
寒冷纷飞旳雪 2024-10-31 13:06:00

如果你把除法当作减法,它基本上是什么,你可以使用一种“减量”方法,它允许你根本不使用任何运算符,除了最后的 ~ ,稍后将结果反转为正整数或任何其他值。

private static int decrement(int i) {

    System.out.println("Value of decrement : ");
    System.out.println(i);
    return i - 1;
}

private static int divide(int n, int d) {

    assert n > 0 && d > 0;
    int counter = 0;
    while (n >= d) {
        for (int i = d; i > 0; i = decrement(i)) {

            n = decrement(n);
        }
        counter = decrement(counter);

    }
    counter  =~decrement(counter);
    System.out.println(counter);
    return counter;
}

If you take the division as a subtraction, what it basically is, you could use a method "decrement" what allows you to not use any operator at all, except for ~ at the end, to invert the result later into a positive integer or any other value.

private static int decrement(int i) {

    System.out.println("Value of decrement : ");
    System.out.println(i);
    return i - 1;
}

private static int divide(int n, int d) {

    assert n > 0 && d > 0;
    int counter = 0;
    while (n >= d) {
        for (int i = d; i > 0; i = decrement(i)) {

            n = decrement(n);
        }
        counter = decrement(counter);

    }
    counter  =~decrement(counter);
    System.out.println(counter);
    return counter;
}
自由如风 2024-10-31 13:06:00

好吧,让我们看看... x/y = e^(ln(x)-ln(y))

well, let's see... x/y = e^(ln(x)-ln(y))

伏妖词 2024-10-31 13:06:00
    private int divideBy2(int number){

    int count = 1;
    while(count<=number){

        if(count*2==number){

            return count;
        }
        count++;
    }
    return count;

}
    private int divideBy2(int number){

    int count = 1;
    while(count<=number){

        if(count*2==number){

            return count;
        }
        count++;
    }
    return count;

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文