题目:
给定两个整数的被除数和除数,在不使用乘法、除法和余运算符的情况下对两个整数进行除法;返回商;向零截断。
被除数和除数都是32位带符号整数;除数永远不会是0
假设我们处理的环境只能存储32位带符号整数范围内的整数:[- 2^31,2^31 - 1]。对于这个问题,假设函数在除法结果溢出时返回2^31 - 1。
Given two integers dividend
and divisor
, divide two integers without using multiplication, division and mod operator.
Return the quotient after dividing dividend
by divisor
.
The integer division should truncate toward zero.
Input: dividend = 10, divisor = 3 Output: 3
Input: dividend = 7, divisor = -3 Output: -2
Note:
Both dividend and divisor will be 32-bit signed integers.
The divisor will never be 0.
Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. For the purpose of this problem, assume that your function returns 231 − 1 when the division result overflows.
参考:
https://blog.csdn.net/makuiyu/article/details/43417749
思路:
(更具体的思路可见参考)
【当N和m都为正数时】
被除数N 除数m
由于每个数都可以表示为:
试着将被除数表示为:(a1,a2,……,an不一定是1、2、3……)
因此N可以表示为m的倍数:
因此,用count记录当前倍数,每次找出当前最小的使下式成立的ai,
令:
且:
其中2的次方可用位运算实现
最后当newN < m时,停止运算,此时的count为所要求的倍数
【注意】
符号方面:上面的算法为当N和m都为正数时,因此需要额外记录符号,再将N和m都转化为其自己的绝对值
边界方面:
为了防止溢出,使用long来进行计算,但是返回值需要是int类型,因此在转换时需要判断是否超出正负边界,超出则输出边界值
代码:
class Solution {
public int divide(int dividend, int divisor) {
if(dividend==0) {
return 0;
}
long count = 0;
long i = 1;
// 1正 -1负
int flag = ((dividend>0 && divisor>0)||(dividend<0 && divisor<0))?1:-1;
long l_dividend = Math.abs((long)dividend);
long l_divisor = Math.abs((long)divisor);
// 寻找倍数
while(l_dividend >= l_divisor) {
while(l_dividend >= l_divisor * i ) {
i = i<<1;
}
i = i>>1;
count = count + i;
l_dividend = l_dividend - l_divisor * i;
i=1;
}
// 边界处理
int MAX_ = 2147483647;
int MIN_ = -2147483648;
if(flag<0) {
count = -count;
if(count<MIN_) {
return MIN_;
}
}else {
if(count>MAX_) {
return MAX_;
}
}
return (int)count;
}
}