题目:Divide Two Integers
不用除法运算符,计算两个整数相除。
注意:
1、除数为零,
2.最小负数转为正数时溢出的情况。(-2147483648/-1 = 2147483648 > 2147483647)
3.正负号
/*******************************************************************************
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
*******************************************************************************/
#include<stdio.h>
#define MAX_INT 2147483647
int divide(int dividend, int divisor) {
if(divisor == 0)return MAX_INT;//除数为零
if(divisor == -1 && dividend == -2147483648)return MAX_INT;//被除数为int的最小数(-2147483648),除数为-1,此时由于int整数最大只能为2147483647,会溢出
int flag = 1;
if(dividend > 0){//计算符号
dividend = -dividend;
if(divisor > 0){
divisor = -divisor;
}else{
flag = -1;
}
}else{
if(divisor > 0){
divisor = -divisor;
flag = -1;
}
}
int count = 0,result = 0;
for(int i = 0;i > dividend;){//计算绝对值
i += divisor;
result--;
}
if(flag > 0){
return -result;
}else{
return result;
}
}
void main(){
printf("%d
",divide(2147483647,1));
}
但是上面的做法效率太低,无法通过。
考虑用左移的方法,速度更快。
思路:
1.为了避免溢出将数据变成long long型。
2.计算结果的符号
3.左移,找左移的最小位数,使得除数左移该位数时正好超过被除数。
4.从上面找到的位数开始每次减少一位,被除数减去当前左移的位数,结果加上1左移同样的位数的值。
数学表示:109/3 = 1101101/11
第三步即找到11000000 = 11 << 6 < 1101101 < 1100000 = 11 << 5中的6这个数,
第四步从5开始循环,每次减1,被除数109第一次循环减去96(1100000)得到13,如此减下去直到小于除数3;
/*******************************************************************************
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
*******************************************************************************/
#include<stdio.h>
#include<math.h>
#define MAX_INT 2147483647
typedef long long Long;//32位C编译器中long和int都是4字节,16位编译器中int是2字节long是4字节
int divide(int dividend, int divisor) {
if(divisor == 0)return MAX_INT;
int flag;
Long dividendL,divisorL;
if(dividend < 0){//计算符号,并转成long long类型
flag = -1;
dividendL = -(Long)dividend;
}else{
flag = 1;
dividendL = (Long)dividend;
}
if(divisor > 0){
divisorL = (Long)divisor;
}else{
flag = -flag;
divisorL = -(Long)divisor;
}
int count = 0,result = 0;
Long temp = divisorL;
while(temp < dividendL){//左移,找到除数左移超过被除数的最小位数
temp = temp << 1;
count++;
}
for(int i = count - 1;i >= 0;i--){
if(dividendL >= (divisorL << i)){
dividendL = dividendL - (divisorL << i);
result += (1 << i);
}
}
if(dividendL == divisorL)result++;//若temp==dividendL时,此时dividendL==divisorL
if(flag > 0){
if(result < 0)return MAX_INT;
return result;
}else return -result;
}
void main(){
printf("%d
",divide(-2147483648,-1));
}
同类型的题目:http://www.cnblogs.com/yeqluofwupheng/p/6755610.html