29. Divide Two Integers
Posted manual-linux
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了29. Divide Two Integers相关的知识,希望对你有一定的参考价值。
思路:这道题让我们求两数相除,而且规定我们不能用乘法,除法和取余操作,那么我们还可以用另一神器 位操作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
以上是关于29. Divide Two Integers的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 29. Divide Two Integers