1 移位運(yùn)算符
<< 左移(進(jìn)位):低位補(bǔ)0
>> 右移:若符號(hào)拓展,為正時(shí),補(bǔ)0;為負(fù)時(shí),補(bǔ)
>>> 無符號(hào)右移
<<< 無符號(hào)左移
1.1 offer10計(jì)算二進(jìn)制中的1的個(gè)數(shù)
錯(cuò)誤解法:若輸入一個(gè)負(fù)數(shù),則程序陷入死循環(huán)
解題過程:通過將輸入數(shù)num右移操作,與1做“與”運(yùn)算來判斷此位二進(jìn)制是否為1;負(fù)數(shù)的最高位會(huì)設(shè)為1,右移操作至0xFFFFFFFF陷入死循環(huán)
public static int countNum1(int num) {
//如果輸入一個(gè)負(fù)數(shù),則程序陷入死循環(huán)
int count=0;
while(num!=0){
if((num&1)!=0){
count++;
}
num>>=1;
}
return count;
}
常規(guī)解法1:通過左移比較值1,來與輸入值num進(jìn)行“與”運(yùn)算,直至0;
public static int countNum2(int num) {
//常規(guī)解法1
int count=0,k=1;
while(k!=0){
if((num&k)!=0){
count++;
}
k<<=1;
}
return count;
}
巧妙解法2:當(dāng)一個(gè)整數(shù)減去1,再和原整數(shù)做“與”運(yùn)算,就會(huì)把原整數(shù)最右邊的一個(gè)1變成0;
public static int countNum3(int num) {
//巧妙解法2
int count=0;
while(num!=0){
count++;
num&=(num-1);
}
return count;
}
注意:在計(jì)算機(jī)中,負(fù)數(shù)以其正值的補(bǔ)碼形式表達(dá)
2 按位運(yùn)算符
& 與:同時(shí)為1時(shí),才為1
| 或:有1存在時(shí),即為1
^ 異或:倆值不相同時(shí),才為1
~ 取反:取反+1為補(bǔ)碼
2.1 位運(yùn)算實(shí)現(xiàn)四則運(yùn)算
加法
public static int addComputing(int a,int b){
//循環(huán)解法
int answer=a;
while(b!=0){
answer=a^b;
b=(a&b)<<1;
a=answer;
}
return answer;
}
public static int addComputing2(int a,int b){
//遞歸解法
return b!=0?addComputing(a^b, (a&b)<<1):a;
}
減法:調(diào)用加法,a-b即a+(-b);取反加1為補(bǔ)碼
public static int minusComputing(int a,int b){
return addComputing(a, addComputing(~b,1));
}
乘法:
public static int multiComputing(int a,int b){
//測試用例:(10,-10)(-10,10)(-10,-10)(0,10)(10,0)
if(b<0&&a<0){
a=addComputing(~a,1);
b=addComputing(~b,1);
}else if(b<0){
int temp=b;
b=a;
a=temp;
}
int answer=0;
while(b!=0){
if((b&1)!=0){
answer=addComputing(answer, a);
}
a<<=1;b>>=1;
}
return answer;
}
除法:注意正負(fù)號(hào)
public static int divideComputing(int a,int b){
if(b==0){
System.out.println("error data b");
return 0;
}
boolean checksign=false;
if(a<=0&&b<0){
a=AddComputing.addComputing(~a, 1);
b=AddComputing.addComputing(~b, 1);
}else if(b<0){
b=AddComputing.addComputing(~b, 1);
checksign=true;
}else if(a<=0){
a=AddComputing.addComputing(~a, 1);
checksign=true;
}
int count=0;
while(a>=b){
a=MinusComputing.minusComputing(a, b);
count++;
}
if(checksign){
count=AddComputing.addComputing(~count, 1);
}
return count;
}