package Java_Interview_Book;
/**
* 位运算实现加减乘数、判断一个数是否是2的N次方
* @author hexiaoli
* 剑指offer(11)二进制中1的个数
*/
public class BitOperation {
//用位运算实现乘法操作
//用位运算实现加法,不考虑进位的加法相当于异或,只考虑进位相当于与之后左移一位
//直到第二步结果为0,剑指offer上面的题
public static int add(int num1,int num2) {
while (num2!=0) {
int temp = num1^num2;
num2 = (num1&num2)<<1;
num1 = temp;
}
return num1;
}
//减法实现,相当于被减数取反加1(用上一步实现的ADD),然后在进行加法运算。
public static int substract(int num1,int num2) {
int subtractor = add(~num2, 1);// 先求减数的补码(取反加一)
int result = add(num1, subtractor); // add()即上述加法运算
return result ;
}
//考虑数值正负的问题
public static int multiply(int num1,int num2) {
//取绝对值
int num1_change = num1 > 0?num1:add(~num1, 1);
int num2_change = num2 > 0?num2:add(~num2, 1);
//计算绝对值化后的乘积
int result = 0;//转化为加法
int count = 0;//被乘数执行的次数
while(count<num2_change) {
result = add(result, num1_change);
count = add(count, 1);
}
//确定乘积的符号
if((num1^num2)<0) {// 只考虑最高位,如果两个数异号,则异或后最高位为1;如果同号,则异或后最高位为0;
result = add(~result,1);
}
return result;
}
public static int divide(int num1,int num2) {
//取绝对值
int dividend = num1 > 0?num1:add(~num1, 1);//被除数
int divisor = num2 > 0?num2:add(~num2, 1);//除数
int reminder = 0;//余数
int quotient = 0;//商
//一直用除数减去被除数,直到被除数小于除数
while(dividend>=divisor) {
quotient = add(quotient, 1);
dividend = substract(dividend, divisor);
}
//确定商的符号
if((dividend^divisor)<0) {// 只考虑最高位,如果两数异号,则异或后最高位为1;如果同号,则异或后最高位为0;
quotient = add(~quotient,1);
}
//确定余数的符号
reminder =divisor>0?dividend:add(~dividend,1);
return quotient;
}
public static boolean isPower(int n) {
if(n<1) return false;
int m =n&(n-1);
return m == 0;
}
public static void main(String[] args) {
int a = 5;
int b =-2;
System.out.println(add(a, b));
System.out.println(substract(a, b));
System.out.println(multiply(a, b));
System.out.println(divide(a, b));
System.out.println(isPower(2));
}
}