位运算效率高,直接怼代码,里面有注解
public class Code02_Bit {
public static void main(String[] args) {
int a, b;
int sumTimes = 100000;
System.out.println("开始测试");
while (sumTimes-- > 1) {
a = (int) (Math.random() * 10);
b = (int) (Math.random() * 20);
/* if ((a + b) != bitAdd(a, b)) {
System.out.println(a + "+" + b + "=" + bitAdd(a, b));
throw new RuntimeException("位运算加法出现问题了!!");
}
if ((a - b) != bitMinus(a, b)) {
throw new RuntimeException("位运算减法出现问题了!!");
}*/
if ((a * b) != bitMulti(a, b)) {
throw new RuntimeException("位运算乘法出现问题了!!");
}
}
System.out.println("结束测试");
System.out.println("开始测试取反");
a = 10;
System.out.println(String.format("%s的取反(~%s)等于%s", a, a, ~a));
System.out.println("结束测试取反");
}
/**
* 两数相加(最好的方式,没有出现“+”号)
*
* @param a
* @param b
* @return
*/
private static int bitAdd(int a, int b) {
// 不能为sum=0,否则当b=0,但a不等于0时,返回sum=0
int sum = a;
while (b != 0) {
sum = a ^ b;
b = (a & b) << 1;
a = sum;
}
return sum;
}
/**
* 两数相减
* 相当于a+(-b):a加上b的相反数
*
* @param a
* @param b
* @return
*/
private static int bitMinus(int a, int b) {
return bitAdd(a, negNum(b));
}
/**
* 两数相乘
* 4*6 <==>00000100*00000110
* 00000100
* * 00000110
* -----------
* 00001000
*+ 00010000
* ------------
* 00011000
* =>16+8=24
*
* @param a
* @param b
* @return
*/
private static int bitMulti(int a, int b) {
int res = 0;
while (b != 0) {
if ((b & 1) != 0) {
res = bitAdd(res, a);
}
a <<= 1;
b >>>= 1;
}
return res;
}
/**
* 两数相除,不能直接计算Integer.MIN_VALUE,
* 因为这里涉及取绝对值
* 24/4 = 6 <==>
* 00000100*00000110
* 00000100*00000100 + 00000100*00000010
* 00010000+00001000
* =16+8=24
*
* 注意:向下取整 18/7 《=》14/7 = 2
* @param a
* @param b
* @return
*/
public static int biDiv(int a, int b) {
// 如果是负数,转成相反数
int x = isNeg(a) ? negNum(a) : a;
int y = isNeg(b) ? negNum(b) : b;
int res = 0;
// x/y
// 非负数,所以不需要从31位开始
for (int i = 30; i >=0 ; i--) {
if ((x >> i) >= y){
res |= (1<<i);
x = bitMinus(x,y<<i);
}
}
// 正正|负负得正,正负|负正得负
return isNeg(a) ^ isNeg(b) ? negNum(res) :res;
}
/**
* 位运算除法统一入口
*
* @param a
* @param b
* @return
*/
public static int divide(int a, int b) {
if (a == Integer.MIN_VALUE && b == Integer.MIN_VALUE) {
return 1;
} else if (b == Integer.MIN_VALUE) {
return 0;
} else if (a == Integer.MIN_VALUE) {
if (b == negNum(1)) {
return Integer.MAX_VALUE;
} else {
/**
* example: 假设范围-15~14
* 计算 -15/3?
* 由于|-15|越界了,明显不行
* 思路:(-15+1)/3 = -4
* -15-(3*(-4)) = -3
* -3/3 = -1
* 结果:-4+(-1)=-5
*/
int c = biDiv(bitAdd(a, 1), b);
return bitAdd(c, biDiv(bitMinus(a, bitMulti(c, b)), b));
}
} else {
return biDiv(a, b);
}
}
/**
* 是否是正数
* @param n
* @return
*/
public static boolean isNeg(int n){
return n < 0;
}
/**
* 求a的相反数
* <p>
* ~9 = -10
* ~10 = -11
*
* @param a
* @return
*/
private static int negNum(int a) {
return bitAdd(~a, 1);
}