29. 两数相除
移位
- 任何正整数都可以用 Math.pow(2,0)+Math.pow(2,1)+...+Math.pow(2,n) 表示。
- 利用 10/3 =(6+4)/3=2+1=3求解 为了方便计算需要把数都转化为正数,为了防止数值溢出int,转换为long。
public class Solution2
{
public int Divide(int dividend, int divisor)
{
//先判断特殊情况
if (divisor == 0 || dividend == 0) return 0;
if (dividend == Int32.MinValue && divisor == -1) return Int32.MaxValue; //防止越界
//利用 10/3 =(6+4)/3=2+1=3求解 为了方便计算需要把数都转化为正数,为了防止数值溢出int,转换为long。
int sign1 = 1;
int sign2 = 1;
int answer = 0;
long dividendLong = dividend;
long divisorLong = divisor;
if (dividend < 0)
{
sign1 = -1;
dividendLong *= -1;
}
if (divisor < 0)
{
sign2 = -1;
divisorLong *= -1;
}
for (int i = 31; i >= 0; i--)
{
if (divisorLong << i <= dividendLong)
{
dividendLong -= divisorLong << i;
answer += (1 << i);
}
}
return answer * sign1 * sign2;
}
}
public class Solution3
{
private int Search(int m, int n)
{
if (m > n) return 0; //当被除数比除数的绝对值还小的时候结束
int k = -1, t = n;
while (m < t && m - t < t) //m-t<t 不能修改成 m<2t (可能会越界)
{
//使用2的幂次进行求解
t = t << 1;
k = k << 1;
}
return k + Search(m - t, n);
}
public int Divide(int dividend, int divisor)
{
int mFlag = dividend > 0 ? -1 : 1;
int nFlag = divisor > 0 ? -1 : 1;
int flag = -1 * mFlag * nFlag;
//将值转换为负值进行计算
int m = dividend * mFlag, n = divisor * nFlag;
int r = Search(m, n);
if (r == Int32.MinValue && flag == -1)
{
return Int32.MaxValue;
}
return r * flag;
}
}