位操作運算符

Java的位運算(bitwise operators)直接對整數類型的位進行操作,這些整數類型包括longintshortchar byte,位運算符具體如下表:

運算符

說明

<< 

左移位,在低位處補0

>> 

右移位,若爲正數則高位補0若爲負數則高位補1

>>> 

無符號右移位,無論正負都在高位補0

&

與(AND),對兩個整型操作數中對應位執行布爾代數,兩個位都爲1時輸出1,否則0

|

或(OR),對兩個整型操作數中對應位執行布爾代數,兩個位都爲0時輸出0,否則1

~

非(NOT),一元運算符。

^

異或(XOR),對兩個整型操作數中對應位執行布爾代數,兩個位相等0,不等1

<<=

左移位賦值。

>>=

右移位賦值。

>>>=

無符號右移位賦值。

&=

按位與賦值。

|=

按位或賦值。

^=

按位異或賦值。

左右位移

向左位移:乘以2的次冪

向右位移:除以2的次冪





左移位(<<)

程序:

public class LeftMoving{

    public static void main(String[] args){

           System.out.println("5<<3="+(5<<3));

    }

}

輸出結果:

5<<3=40

計算過程:

0000 0000 0000 0000 0000 0000 0000 0101         ? 5

0000 0000 0000 0000 0000 0000 0010 1000         ? 40

5<<3 //等價於 5*(2^3) 5乘上2的3次冪


右移位(>>)

正數

程序:

public class PlusRightMoving{

    public static void main(String[] args){

           System.out.println("5>>1="+(5>>1));

    }

}

輸出結果:

5>>1=2

計算過程:

0000 0000 0000 0000 0000 0000 0000 0101         ? 5

0000 0000 0000 0000 0000 0000 0000 0010         ? 2

負數

程序:

public class NegativeRightMoving{

    public static void main(String[] args){

           System.out.println("-5>>1="+(-5>>1));

    }

}

輸出結果:

-5>>1=-3

計算過程:

1111 1111 1111 1111 1111 1111 1111 1011         ? -5

1111 1111 1111 1111 1111 1111 1111 1101         ? -3

無符號右移位(>>>)

程序:

public class UnsignedRightMoving{

    public static void main(String[] args){

           System.out.println("-5>>>1="+(-5>>>1));

    }

}

輸出結果:

-5>>>1=2147483645

計算過程:

1111 1111 1111 1111 1111 1111 1111 1011         ? -5

       0111 1111 1111 1111 1111 1111 1111 1101          ? 2147483645

 

首先複習一下Java中的基本數據類型的相關知識。

數據類型

大小

最小值

最大值

boolean

 

 

 

byte

8-bit

-128

+127

char

16-bit

Unicode 0

Unicode 216-1

short

16-bit

-215

+215-1

int

32-bit

-231

+231-1

float

32-bit

IEEE754

IEEE754

long

64-bit

-263

263-1

double

64-bit

IEEE754

IEEE754

void

 

 

 

這裏包括了floatdouble兩個浮點型,在本文中對其不予考慮,因爲位運算是針對整型的。進行位操作時,除long型外,其他類型會自動轉成int型,轉換之後,可接受右操作數長度爲32。進行位運算時,總是先將短整型和字節型值轉換成整型值再進行移位操作的。

程序:

public class ByteLeftMoving{

public static void main(String[] args){

    byte b = 127;

           System.out.println("b<<3="+(b<<3));

        System.out.println("(byte)(b<<3)="+(byte)(b<<3));

    }

}

輸出結果:

b<<3=1016

(byte)(b<<3)=-8

程序:

public class CharLeftMoving{

public static void main(String[] args){

        char c = 'l';

           System.out.println("c<<3="+(c<<3));

        System.out.println("(char)(c<<3)="+(char)(c<<3));

    }

}

輸出結果:

c<<3=864

(char)(c<<3)=?

以上兩個例子全部編譯通過,由此可以看出,當bytechar進行移位運算時不會發生錯誤,並且均按照整型進行計算,當計算結果超出byte或是char所能表示的範圍時則進行相應的轉換(分別輸出了結果-8?)。


位運算中的操作數

在進行移位運算時要注意整型和長整型在內存中的位數(整型是32位,長整型是64位),如果移位操作數超出了該位數則取模計算,例如:int型數據是32位的,如果左移35位是什麼結果?

程序:

public class LeftMoving{

    public static void main(String[] args){

           System.out.println("5<<35="+(5<<35));

    }

}

輸出結果:

5<<35=40 

該結果與5<<3完全相同。

 

無論正數、負數,它們的右移、左移、無符號右移 32位都是其本身,比如 -5<<32=-5-5>>32=-5-5>>>32=-5

一個有趣的現象是,把 1 左移 31 位再右移 31位,其結果爲 -1

計算過程如下:

0000 0000 0000 0000 0000 0000 0000 0001

1000 0000 0000 0000 0000 0000 0000 0000

1111 1111 1111 1111 1111 1111 1111 1111

 

位運算要求操作數爲整數,操作數不能是字符串也不能是小數。

如下列程序:

public class BitMath{

    public static void main(String[] args){

        String s = "Hello";

        long l = 99;

        double d = 1.11;

        int i = 1;

        int j = 0;

 

        System.out.println("j<<s="+j<<s);    //編譯錯誤語句

        System.out.println("j<<d="+j<<d);    //編譯錯誤語句

        System.out.println("i<<j="+i<<j);    //編譯可以通過

        System.out.println("i<<l="+i<<l);    //編譯可以通過

    }

}



由於位運算是二進制運算,不要與一些八進制數搞混,java中二進制數沒有具體的表示方法。

public class BitMath{

    public static void main(String[] args){

        System.out.println("010|4="+(010|4));

    }

}

輸出結果:

010|4=12

計算過程:

0000 0000 0000 0000 0000 0000 0000 1000   ?8

0000 0000 0000 0000 0000 0000 0000 0100   ?4

進行“或”計算結果爲:

0000 0000 0000 0000 0000 0000 0000 1100   ?12

當位運算中遇見負數,必須把它轉成補碼(不知道什麼是補碼的補習功課去)再進行計算,而不是使用原碼。

程序:

public class BitMath{

    public static void main(String[] args){

        try {

            int x = -7;

            System.out.println("x>>1="+(x>>1));

} catch(Exception e) {

            System.out.println("Exception");

        }

    }

}

輸出結果:

x>>1=-4

計算過程:

1111 1111 1111 1111 1111 1111 1111 1001   ?-7

1111 1111 1111 1111 1111 1111 1111 1100    ?-4

public class BitMath{

    public static void main(String[] args){

        int i = 1;

        int j = -1;

        System.out.println("1>>>31="+(i>>>31));

        System.out.println("-1>>31="+(j>>31));

    }

}

輸出結果:

1>>>31=0

-1>>31=-1

程序:

public class BitMath{

    public static void main(String[] args){

        int a = 1;

       a <<= 31;

        a >>= 31;

        a >>= 1;       

        System.out.println("a="+a);

 

        int b = 1;

        b <<= 31;

        b >>= 31;

        System.out.println("b="+b);

 

        int c = 1;

        c >>= 31;

        c <<= 31;

        System.out.println("c="+c);

    }

}

輸出結果:

a=-1

b=-1

c=0

計算過

發佈了24 篇原創文章 · 獲贊 22 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章