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.
解决方案
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;
}