如何优化除法和取模,一般来说有下的解决方案
对于除数为 2 的 n 次方的,可以采用位逻辑运算符的形式
比如 22/16 可以等价为 22>>4,;22%4 可以等价位 22-(22>>4<<4);
但如果是不其他数,比如 2344/3,45/3 ,那么该怎么办?
是否可以这样这样想,除法可以转换成减法,比如 12/3 等以认为是 12-3-3 -3-3=0;
用代码可以这样表示
//假设 a/b =c-----d
c=0;
While(a>=b)
{
a-=b;
c++;
}
return c;
结合 12/3 来具体分析一下,
第一次循环 a=9;c=1;
第二次循环 a=6;c=2;
第三次循环 a=3;c=3;
第四次循环 a=0;c=4;
第五次循环 终止
通过这个方法是可以实现我们的要求的
但是对于含有负数的情况怎么办?首先我举几个例子
11 / 3 = 3;
-11 / -3 = 3;
-11 / 3 = -3;
11/-3 = -3
由此可以发现,我们得出以下结论
正 / 正 = 正
负 / 负 = 正
负 / 正 = 负
正 / 负 = 负
因此可以把 2-4 种情况,转化为第一种情况,在对结果进行转化
此外应该注意某些非法的输入,比如除数为零,数值过大等等
那取模怎么办, 事实上,它跟除法差不多,他的核心代码如下
While(a>=b)
{
a-=b;
}
Return a;
不同的是,他返回时 a ;
当然取模也有四种情况:
正 / 正 = 正
负 / 负 = 负
负 / 正 = 负
正 / 负 = 正
同样的道理,也可以把 2-4 种情况,转化为第一种情况,在对结果进行转化。
最后代码如下
public class Operation
{
/** 关于整数的除法运算
*
*/
public static int div(int a,int b)
{
//还有一些可能的异常,没有写出来
//如果被除数为0
if(b ==0) throw new ArithmeticException("除数不能为零");
//如果a正,b正
if(a>=0 && b>= 0)
return division(a,b);
//如果a负,b负
else if(a<0 && b <0)
return division(-a,-b);
//如果a正,b负
else if(a >= 0 && b < 0)
return -division(a,-b);
//如果a负,b正
else return -division(-a,b);
}
private static int division(int a,int b)
{
int count = 0;
while(a >= b)
{
a-=b;
count++;
}
return count;
}
/** 关于整数的取模运算
*
*/
public static int mod(int a,int b)
{
//还有一些可能的异常,没有写出来
//如果被除数为0
if(b ==0) throw new ArithmeticException("除数不能为零");
//如果a正,b正
if(a>=0 && b> 0)
return modulo(a,b);
//如果a负,b负
else if(a<0 && b <0)
return -modulo(-a,-b);
//如果a正,b负
else if(a >= 0 && b < 0)
return modulo(a,-b);
//如果a负,b正
else return -modulo(-a,b);
}
private static int modulo(int a,int b)
{
int count = 0;
while(a >= b)
{
a-=b;
}
return a;
}
public static void main(String[] args) throws Exception
{
System.out.println(Operation.div(11,3));
System.out.println(Operation.div(-11,-3));
System.out.println(Operation.div(-11,3));
System.out.println(Operation.div(11,-3));
System.out.println(Operation.mod(11,3));
System.out.println(Operation.mod(-11,-3));
System.out.println(Operation.mod(-11,3));
System.out.println(Operation.mod(11,-3));
}
}