Divide two integers without using multiplication, division and mod operator in java

一曲冷凌霜 提交于 2020-04-14 09:05:03

问题


I write down a code which find out quotient after dividing two number but without using multiplication,division or mod operator.

My code

public int divide(int dividend, int divisor) {

    int diff=0,count=0;
    int fun_dividend=dividend;
    int fun_divisor=divisor;
    int abs_dividend=abs(dividend);
    int abs_divisor=abs(divisor);

    while(abs_dividend>=abs_divisor){
        diff=abs_dividend-abs_divisor;

        abs_dividend=diff;
        count++;

    }

    if(fun_dividend<0 && fun_divisor<0){
        return count;
    }
    else if(fun_divisor<0||fun_dividend<0) {
        return (-count);
    }

    return count;

}

My code passes the test cases like dividend=-1, divisor=1 or dividend=1 and divisor=-1. But it cannot pass the test case like dividend = --2147483648 and divisor =-1. However I have a if statement when both inputs are negative.

  if(fun_dividend<0 && fun_divisor<0){
        return count;
    }

When my inputs are -2147483648 and -1 it returned zero. I debugged my code and find out that it cannot reach the the inner statements of while loop. It just check the while loop and terminated and execute

 if(fun_dividend<0 && fun_divisor<0){
        return count;
    }

It is very obvious, both inputs are negative, so I was using Math.abs function to make them positive. But when I try to see the values of variables abs_dividend and abs_divisor they show me negative values.

Integer max can take a 9 digit number. So how could I pass this test case? As per this test case dividend is a 10 digit number which is not valid for a integer range.

As per the test case the output that I get should be 2147483647.

How could I solve the bug?

Thank you in advance.


回答1:


I solve it this way. Give preference to data type long over int wherever there is a chance of overflow upon left-shift. Handle the edge case at the very beginning to avoid the input values getting modified in the process. This algorithm is based upon the division technique we used to make use in school.

public int divide(int AA, int BB) {
    // Edge case first.    
    if (BB == -1 && AA == Integer.MIN_VALUE){
        return Integer.MAX_VALUE;   // Very Special case, since 2^31 is not inside range while -2^31 is within range.
    }
    long B = BB;
    long A = AA;

    int sign = -1;
    if ((A<0 && B<0) || (A>0 && B>0)){
        sign = 1;
    }
    if (A < 0) A = A * -1;
    if (B < 0) B = B * -1;

    int ans = 0;
    long currPos = 1; // necessary to be long. Long is better for left shifting.
    while (A >= B){
        B <<= 1; currPos <<= 1;
    }
    B >>= 1; currPos >>= 1;
    while (currPos != 0){
        if (A >= B){
            A -= B;
            ans |= currPos;
        }
        B >>= 1; currPos >>= 1;
    }
    return ans*sign;
}



回答2:


Try using the bit manipulation for this as follows:

public static int divideUsingBits(int dividend, int divisor) {
        // handle special cases
        if (divisor == 0)
            return Integer.MAX_VALUE;
        if (divisor == -1 && dividend == Integer.MIN_VALUE)
            return Integer.MAX_VALUE;

        // get positive values
        long pDividend = Math.abs((long) dividend);
        long pDivisor = Math.abs((long) divisor);

        int result = 0;
        while (pDividend >= pDivisor) {
            // calculate number of left shifts
            int numShift = 0;
            while (pDividend >= (pDivisor << numShift)) {
                numShift++;
            }

            // dividend minus the largest shifted divisor
            result += 1 << (numShift - 1);
            pDividend -= (pDivisor << (numShift - 1));
        }

        if ((dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0)) {
            return result;
        } else {
            return -result;
        }
    }



回答3:


Ran with the debugger and found that abs_dividend was -2147483648.

Then the comparison in while (abs_dividend >= abs_divisor) { is false and count is never incremented.

Turns out the explanation is in the Javadoc for Math.abs(int a):

Note that if the argument is equal to the value of Integer.MIN_VALUE, the most negative representable int value, the result is that same value, which is negative.

Presumably, this is because Integer.MAX_VALUE is 2147483647, so there is no way of representing positive 2147483648 with an int. (note: 2147483648 would be Integer.MAX_VALUE + 1 == Integer.MIN_VALUE)



来源:https://stackoverflow.com/questions/54058038/divide-two-integers-without-using-multiplication-division-and-mod-operator-in-j

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!