思路:這道題讓我們求兩數相除,而且規定我們不能用乘法,除法和取余操作,那么我們還可以用另一神器 位操作Bit Operation,思路是,如果被除數大於或等於除數,則進行如下循環,定義變量t等於除數,定義計數p,當t的兩倍小於等於被除數時,進行如下循環,t擴大一倍,p擴大一倍,然后更新res和m。這道題的OJ給的一些test case非常的討厭,因為輸入的都是int型,比如被除數是-2147483648,在int范圍內,當除數是-1時,結果就超出了int范圍,需要返回INT_MAX,所以對於這種情況我們就在開始用if判定,將其和除數為0的情況放一起判定,返回INT_MAX。然后我們還要根據被除數和除數的正負來確定返回值的正負,這里我們采用長整型long來完成所有的計算,最后返回值乘以符號即可。
用到的知識:左移1位,相當於乘2,右移1位,相當除以2。
第一次提交
int divide(int dividend, int divisor)
{
int INTMAX = 2147483647;
int INTMIN = -2147483648;
if(divisor == 0)
{
return INTMAX;
}
if(dividend == INTMIN && divisor == -1)
{
return INTMAX;
}
if(dividend == divisor)
{
return 1;
}
long long divid = abs((long long)dividend); //第17行
long long divis = abs((long long)divisor);
long res = 0;
//做符號判斷 //判斷兩個數符號是否相同,可使用按位異或
int sign = ((dividend < 0) ^ (divisor < 0)) ? -1 : 1; //同號sign=1,異號sign=0
if((divisor == 1) || (divisor == -1))
{
return sign == 1 ? divid : -divid;
}
//做除法
while(divid > divis)
{
long long t = divis ,p =1;
while(divid >= (t << 1)) //左移1位等價於乘2
{
t = t << 1;
p = p << 1;
}
res = res + p;
divid = divid - t;
}
return sign == 1 ? res : -res;
}
LeEtcode報錯
Line 17: Char 23: runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself (solution.c)
abs的返回值overflow,同時我在本地的編譯器提示我應該使用llabs()函數,abs()函數和llabs()函數的區別如下
int abs( int n );
long labs( long n );
long long llabs( long long n );
__int64 _abs64( __int64 n );
也就是abs()函數的返回值是int類型,當abs()函數的輸入為INT_MIN時,abs()函數將直接返回INT_MIN,這一點在微軟官網上給出了解釋。
我在Qt中做了一個實驗
int main()
{
printf("%d",abs(INT_MIN));
return 0;
}
運行結果如下:
第二次提交
int divide(int dividend, int divisor)
{
int INTMAX = 2147483647;
int INTMIN = -2147483648;
if(divisor == 0)
{
return INTMAX;
}
if(dividend == INTMIN && divisor == -1)
{
return INTMAX;
}
if(dividend == divisor)
{
return 1;
}
long long divid = llabs((long long)dividend);
long long divis = llabs((long long)divisor);
long res = 0;
//做符號判斷 //判斷兩個數符號是否相同,可使用按位異或
int sign = ((dividend < 0) ^ (divisor < 0)) ? -1 : 1; //同號sign=1,異號sign=0
if((divisor == 1) || (divisor == -1))
{
return sign == 1 ? divid : -divid;
}
//做除法
while(divid > divis)
{
long long t = divis ,p =1;
while(divid >= (t << 1)) //左移1位等價於乘2
{
t = t << 1;
p = p << 1;
}
res = res + p;
divid = divid - t;
}
return sign == 1 ? res : -res;
}
參考資料:
1 abs,labs,llabs函數的說明 https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/abs-labs-llabs-abs64?view=vs-2017
2 https://www.cnblogs.com/grandyang/p/4431949.html