位運算

位運算的思考題
1)請看下面的代碼段,回答a,b,c,d,e結果是多少?

    public static void main(String[] args) {
        int a=1>>2;//1向右位移2位
        int b=-1>>2; // -向右位移兩位,算術右移
        int c=1<<2;// 1向左位移2位,算術左移
        int d=-1<<2;-1向左位移兩位
        int e=3>>>2; // 無符號右移
        //a,b,c,d,e結果是多少
        System.out.println("a="+a);
        System.out.println("b="+b);
        System.out.println("C="+c);
        System.out.println("d="+d);
        System.out.println("e="+e);
    }

運算符的優先級

韓順平老師的圖

在Java中,下邊的表達式運算的結果是:(位操作)。

~2=? // 按位取反操作
2&3=?// 2按位與3
2|3=?// 2按位或3
~-5=?// 按位取反
13&7=? // 13按位與7
5|4=?// 5按位或4
-3^3=?// -3按位異或3

二進制在運算中的說明

1.二進制是逢2進位的進位制,0、1是基本算符。
2.現代的電子計算機技術全部采用的是二進制,因為它只使用0、1兩個數字符號,非常簡單方便,易于用電子方式實現。計算機內部處理的信息,都是采用二進制數來表示的。二進制(Binary)數用0和1兩個數字及其組合來表示任何數。進位規則是"逢2進1",數字1在不同的位上代表不同的值,按從右至左的次序,這個值以二倍遞增。

原碼、反碼、補碼

對于有符號的而言:
1.二進制的最高位是符號位:0表示正數,1表示負數(口訣: 0旋轉90度還為0,1旋轉90度為負號“-”)
2.正數的原碼,反碼,補碼都一樣(三碼合一)
3.負數的反碼=它的原碼符號位不變,其它位取反(0->1,1->0)
4·負數的補碼=它的反碼+1,負數的反碼=負數的補碼-1
5.0的反碼,補碼都是0
6.java沒有無符號數,換言之,java中的數都是有符號的
7.在計算機運算的時候,都是以補碼的方式來運算的.
8,當我們看運算結果的時候,要看他的原碼

位運算符

位運算符Java中有7個位運算(&、|、^、~、>>、<<和>>>)
分別是按位與&、按位或|、按位異或^、按位取反~,它們的運算規則是:
按位與&:兩位全為1,結果為1,否則為0.
按位或|:兩位有一個為1,結果為1,否則為0
按位異或^:兩位一個為0,一個為1,結果為1,否則為0
按位取反~:0->1,1->0
比如: 2&3=?、-2=?、2=?、2|3=?、2^3=?

實例1

    public static void main(String[] args) {

        //推導過程
        /**
         * 1、先得到2的補碼
         * 2的原碼:00000000 00000000 00000000 00000010
         * 正數的原碼、反碼、補碼相同(三合一)
         * 2的補碼:00000000 00000000 00000000 00000010
         */

        /**
         * 2、在得到3的補碼
         * 3的原碼:00000000 00000000 00000000 00000011
         * 正數的原碼、反碼、補碼相同(三合一)
         * 3的補碼:00000000 00000000 00000000 00000011
         */

        /**
         * 3、按位與計算2的補碼和3的補碼,兩位全為1,結果為1,否則為0.。(注:計算用補碼、結果用原碼)
         * 2的補碼:00000000 00000000 00000000 00000010
         * 3的補碼:00000000 00000000 00000000 00000011
         *    結果:00000000 00000000 00000000 00000010 (這是運算過后得到的補碼)
         * 我們在運算后的結果需要看原碼,因為符號位是0為正數,1為負數,所以三碼合一
         * 結果的原碼為:00000000 00000000 00000000 00000010
         * 將結果二進制數轉為十進制數為:0*(2的1-1次方)+1*(2的2-1次方)=0+2=2
         * 所以2&3的結果為:2
         */
        System.out.println(2&3);
    }

實例2

        /**
         * 1、先得到-2的原碼:10000000 00000000 00000000 00000010
         * 2、在得到-2的反碼:11111111 11111111 11111111 11111101
         * 3、得到-2的補碼:  11111111 11111111 11111111 11111110
         * 4、取反:         00000000 00000000 00000000 00000001
         * 5、將補碼轉為原碼:00000000 00000000 00000000 00000001
         * 6、將二進制數轉為十進制數,結果為:1
         */
        System.out.println(~-2);

實例3

/**
         * 1、先得到2的原碼:00000000 00000000 00000000 00000010
         * 2、后得到2的補碼:00000000 00000000 00000000 00000010 (正數三碼合一)
         * 3、直接按位取反: 11111111 11111111 11111111 11111101
         * 4、補碼轉為反碼: 11111111 11111111 11111111 11111100 (負數的反碼=負數的補碼-1)
         * 5、反碼轉原碼:   10000000 00000000 00000000 00000011 (負數的反碼=它的原碼符號位不變,其它位取反(0->1,1->0))
         * 6、將二進制原碼轉為十進制結果為:-3
         */
        System.out.println(~2);

其他位運算符

還有3個位運算符>>、<<和>>>,運算規則:
1.算術右移>>:低位溢出,符號位不變,并用符號位補溢出的高位
2.算術左移<<:符號位不變,低位補0
3.>>>邏輯右移也叫無符號右移,運算規則是:低位溢出,高位補0
4,特別說明:沒有<<<符號.

應用案例

/**
         * 1=> 00000000 00000000 00000000 00000001
         * 低位溢出,符號位不變,并用符號位補溢出的高位
         * 1向右移動兩位是:00000000 00000000 00000000 00000000 本質是1/2/2=0
         */
        System.out.println(1>>2);


        /**
         * 1=> 00000000 00000000 00000000 00000001
         * 1>>2:符號位不變,低位補0:00000000 00000000 00000100 本質:1*2*2=4
         */
        System.out.println(1<<2);


        /**
         * 相當于:4*2*2*2=32
         */
        System.out.println(4<<3);

        /**
         * 相當于:15/2/2 = 3
         */
        System.out.println(15>>2);

        /**
         * 相當于:56/2/2/2/2=3
         */
        System.out.println(56>>4);

        /**
         * 相當于:56*2*2*2*2=896
         */
        System.out.println(56<<4);

小插曲

10/3=3
10/5=2
10%2=0
-10.5%3=-1.5(a%b,當a是小數時,公式=a-(int)a/b*b),得到的是近似值
int i = 66;
System.out.println(++i+i);// 結果為66+1+67=134

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容