今日做leetCode的371题算法题,用位运算计算两个数之和。借此机会,将位运算的加减乘除做一整理。
package Algorithm;
public class Code371 {
public static void main(String[] args) {
Code371 code = new Code371();
System.out.println(code.add(27, 35));
System.out.println(code.sub(27, 35));
System.out.println(code.posMutiply(27, 35));
System.out.println(code.mutiply(-27, -35));
System.out.println(code.posDiv(57, 35));
System.out.println(code.div(-57, 35));
System.out.println(code.isPos(35));
System.out.println(code.isNeg(-23));
System.out.println(code.isZero(0));
}
// 加法运算
public int add(int a, int b) {
if (b == 0)
return a;
int sum = a ^ b;
int carry = (a & b) << 1;
return add(sum, carry);
}
// 取补码
public int negtive(int a) {
return add(~a, 1);
}
// 减法运算
public int sub(int a, int b) {
return add(a, negtive(b));
}
// 正数乘法运算
public int posMutiply(int a, int b) {
int ans = 0;
while (b > 0) {
if ((int) (b & 1) > 0)
ans = add(ans, a);
a = (a << 1);
b = (b >> 1);
}
return ans;
}
public int mutiply(int a, int b){
if(isZero(a) || isZero(b)){
return 0;
}
int mutiplyResult = posMutiply(isPos(a)? a: negtive(a), isPos(b)? b:negtive(b));
if(isPos(a) ^ isPos(b)){
return negtive(mutiplyResult);
}
return mutiplyResult;
}
// 正数除法运算
public int posDiv(int x, int y) {
int ans = 0;
for (int i = 31; i >= 0; i--) {
// 比较x是否大于y的(1<<i)次方,避免将x与(y<<i)比较,因为不确定y的(1<<i)次方是否溢出
if ((x >> i) >= y) {
ans += (1 << i);
x -= (y << i);
}
}
return ans;
}
public int div(int x, int y){
if(isZero(y)){
System.exit(1);
}
if(isZero(x)){
return 0;
}
int divResult = posDiv(isPos(x)? x: negtive(x), isPos(y)? y:negtive(y));
if(isPos(x) ^ isPos(y)){
return negtive(divResult);
}
return divResult;
}
// 正数
public boolean isPos(int a) {
return (a & 0xFFFF) != 0 && (a & 0x8000) == 0;
}
// 负数
public boolean isNeg(int a) {
return (a & 0x8000) != 0;
}
// 0
public boolean isZero(int a) {
return (a & 0xFFFF) == 0;
}
}
参考资料
1.用位运算实现四则运算之加减乘除(用位运算求一个数的1/3),CSDN博客,http://blog.csdn.net/hackbuteer1/article/details/7390093