1. 程式人生 > >java移位運算子(運算子)

java移位運算子(運算子)

java運算子有:分隔符、一元運算子、算術運算子、移位運算子、關係運算符、邏輯運算子、三目運算子、賦值運算子;在這裡重點講解的是移位運算子,其它的有些略微提一下,前面博文中已經對位運算子有了初步的理解,可以說這篇博文是上一篇運算子的續集。

算術運算子

所謂算術運算子就是加、減、乘、除,這裡只要講一下不同型別的數字混合運算,相關型別轉換精確度問題。下面給出一張圖,資料是按自動向上造型的原則


型別              儲存需求        bit數                  取值範圍      
byte              1位元組           1*8      (-2的31次方到2的31次方-1)
short             2位元組           2*8             -32768~32767
int               4位元組           4*8      (-2的63次方到2的63次方-1)

long              8位元組           8*8                 -128~127

float              4位元組           4*8            float型別的數值有一個字尾F(例如:3.14F)
double             8位元組           8*8         沒有後綴F的浮點數值(如3.14)預設為double型別

注:

1、實線的箭頭表示沒有資料資訊丟失的轉換,也是安全性轉換

      虛線的箭頭表示有精度損失的轉換,也就是不安全的轉換

     (意思低精度轉高精度資料不會丟失,高精度轉低精度最高位資料可能丟失,所謂精度高低是看佔記憶體位元組大小)


2、當倆個操作型別不相同時,運算元在運算前會自動向上造型成相同的型別,在進行運算

移位運算子

移位運算子操作物件是針對二進位制的位來說的,可以單獨用移位運算子來處理int型的整數。

運算子含義例子
<<左移運算子,規則:將運算子左邊的物件向左移動運算子右邊指定的位數(在低位補0)x<<3
>>"有符號"右移運算子,規則:將運算子左邊的物件向右移動運算子右邊指定的位數。使用符號擴充套件機制,
也就是說,如果值為正,則在高位補0,如果值為負,則在高位補1
x>>3
>>>"無符號"右移運算子,規則:將運算子左邊的物件向右移動運算子右邊指定的位數。採用0擴充套件機制,也就是說,無論值的正負,都在高位補0
x>>>3

正數(符號位為0的數)

負數(符號位為1的數)

有符號右移位情況

正數:

public static void main(String[] args) {
		int a = 666;
		System.out.println("a>>5的結果是:"+(a>>5));
	}
a>>5的結果是:20

    666   =    00000000 00000000 00000010 10011010

666右移5位

666>>5 =   00000000 00000000 00000000 00010100 = 2的4次方 + 2的2次方 = 20

負數:

public static void main(String[] args) {
		int a = -666;
		System.out.println("a>>5的結果是:"+(a>>5));
	}
a>>5的結果是:-21
 十進位制轉換成二進位制的公式Integer.toBinaryString(int i)

        -666      =       11111111 11111111 11111101 01100110

-666右移5位(負數,則在高位補1

-666>>5     =        11111111 11111111 11111111 11101011

-666>>5反碼        10000000 00000000 00000000 00010100

-666>>5補碼        10000000 00000000 00000000 00010101

原碼 = 反碼+1

所以 -666>>5的原碼 = 100000000 00000000 00000000 00010100 +1 = 1000000 00000000 00000000 00010101 = -(2的4次方 + 2的2次方 + 2的0次方) = -21

有符號左移位情況

正數:

public static void main(String[] args) {
		int a = 6;
		System.out.println("a<<5的結果是:"+(a<<5));
	}
a<<5的結果是:192
   6   =    00000000 00000000 00000000 00000110

6左移5位

6<<5 = 00000000 00000000 00000000 11000000 = 2的7次方 + 2的6次方 = 192

負數:

public static void main(String[] args) {
		int a = -6;
		System.out.println("a<<5的結果是:"+(a<<5));
	}
a<<5的結果是:-192
       -6     =    11111111 11111111 11111111 11111010

-6左移5位

   -6<<5   =   11111111 11111111 11111111 01000000

-6<<5反碼   10000000 00000000 00000000 10111111

原碼 = 反碼+1

所以 -6<<5 原碼 = 10000000 00000000 00000000 10111111 + 1 = 10000000 00000000 00000000 11000000 = -192

從上面有符號移位運算髮現一個規則:

1、一個數m左移n位,就是將這個數m乘以2的n次方,既結果=m * 2的n次方

2、一個數m右移n位,就是將這個數m除以2的n次方,既結果=m / 2的n次方

無符號移位運算

正數:

666>>>5

public static void main(String[] args) {
		int a = 666;
		System.out.println("a>>>5的結果是:"+(a>>>5));
	}
a>>>5的結果是:20

    666   =    00000000 00000000 00000010 10011010

666右移5位

666>>>5 =   00000000 00000000 00000000 00010100 = 2的4次方 + 2的2次方 = 20

負數:

-666>>>5

public static void main(String[] args) {
		int a = -666;
		System.out.println("a>>>5的結果是:"+(a>>>5));
	}
a>>>5的結果是:134217707
        -666      =    11111111 11111111 11111101 01100110
-666右移5位(無論值的正負,都在高位補0

 -666>>>5    =     00000111 11111111 11111111 11101011 = 原碼

發現負數的無符號運算數值都比較大,這裡就不作計算了