數(shù)據(jù)結(jié)構(gòu)—位運(yùn)算

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;
    }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容