日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java移位运算符:<<,>>,>>>

發布時間:2024/8/1 java 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java移位运算符:<<,>>,>>> 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java移位運算符:<<,>>,>>>

最近在看jdk的源碼,里面還是有很多地方用到了移位操作的,但是本人因為不怎么使用移位操作,基本是看了過一段時間就忘了,忘了用到的時候再看… …

所以在這里寫下這篇博客,以后如果再忘記了直接翻回來看。


Java中有三種移位運算符,分別是左移運算符(<<),有符號右移(>>),無符號右移(>>>),作用分別如下:

  • 左移運算符(<<):將數值的所有二進制位左移給定的位數,高位即左邊的二進制位溢出則丟棄,低位空出來的部分補0

  • 有符號右移(>>):將數值的所有二進制位右移給定的位數,高位空出來的補符號位,即負數補1,正數補0,;低位溢出的部分直接丟棄

  • 無符號右移(>>>):將數值的所有二進制位右移給定的位數,高位空出來的補0,不論正數還是負數;低位溢出的部分直接丟棄

  • 需要注意的是,移位的所有操作都是對數值的補碼進行操作的!!!

    我們知道數值有原碼、反碼、補碼三種表示形式,在計算機里的整數值都是以補碼的形式存儲的。對于正數來說,原碼=反碼=補碼;對于負數來說,反碼等于原碼除符號位之外各位取反,補碼等于反碼末位加一。

    也就是說我們只需要關心負數的補碼即可,并且負數原碼反碼補碼中轉換的規則是通用的,即原碼=補碼除符號位之外各位取反末位加一,而補碼=原碼除符號位之外各位取反末位加1。當然你也可以先減1然后除符號位之外各位取反。

    補碼:1000 0000 …這樣的數很特殊,它是沒有原碼的。當數值為16位時,10000000 00000000的真值為-32768,32位時10000000 00000000 00000000 00000000的真值為-2147483648。

    我們通過下面的代碼來驗證:

    public class ShiftOptionsDemo {/*** 1(int):* 源碼:00000000 00000000 00000000 00000001* 反碼:與源碼相同* 補碼:與源碼相同** -1(int):* 源碼:10000000 00000000 00000000 00000001* 反碼:11111111 11111111 11111111 11111110* 補碼:11111111 11111111 11111111 11111111** << :左移* >> : 有符號右移* >>> : 無符號右移** 左移會將補碼的所有比特位向左移動* 有符號右移將所有比特位移動后“空出來”的比特位會補符號位,負數補1,正數補0* 無符號右移移動后“空出來”的比特位會補0,不管是正數還是負數** 編譯器(可能不是全部的編譯器)發現移動的位數等于或超過數值本身的位數后,會* 對這個移動的位數進行取模操作, 也就是說一個int型的變量x,x << 32 等價于 x << 1*/public static void main(String[] args) {/** 結果:4* 1補碼* 00000000 00000000 00000000 00000001 = 1* 左移2位后的補碼* 00000000 00000000 00000000 00000100 = 4*/System.out.println(1 << 2);/** 結果:-4* -1補碼* 11111111 11111111 11111111 11111111 = -1* 左移2位后的補碼:* 11111111 11111111 11111111 11111100* 轉換成原碼:* 10000000 00000000 00000000 00000100 = -4*/System.out.println(-1 << 2);/** 結果:0* 1補碼* 00000000 00000000 00000000 00000001 = 1* 有符號右移2位后的補碼:* 00000000 00000000 00000000 00000000 = 0*/System.out.println(1 >> 2);/** 結果:-1* -1補碼* 11111111 11111111 11111111 11111111 = -1* 有符號右移2位后的補碼:* 11111111111111111111111111111111111 = -1*/System.out.println(-1 >> 2);/** 結果:0* 1補碼* 00000000 00000000 00000000 00000001 = 1* 無符號右移2位后的補碼:* 00000000 00000000 00000000 00000000 = 0*/System.out.println(1 >>> 2);/** 結果:1073741823* -1補碼* 11111111 11111111 11111111 11111111 = -1* 無符號右移2位后的補碼:* 00111111 11111111 11111111 11111111 = 1073741823* 這個時候負數就變成了正數*/System.out.println(-1 >>> 2);//輸出:1073741823System.out.println(0b00111111111111111111111111111111);/** 11111111 11111111 11111111 11111111 = -1* 無符號右移一位后的結果:* 01111111 11111111 11111111 11111111 = 2147483647*/System.out.println(-1 >>> 1);//輸出:2147483647System.out.println(0b01111111111111111111111111111111);} }

    大多數情況下,左移1位相當于乘2,有符號右移相當于除2,但是也有很多特殊的數不符合。比如:

    010000000 00000000 00000000 0000000本身是個正數,左移1位后就成負數了,并且就是1000 …這樣的負數了。

    -1有符號右移怎么移都是-1,因為-1的補碼是:11111111 … 11111111,根據有符號右移的規則,-1的二進制補碼再怎么移都還是它本身。

    總結

    以上是生活随笔為你收集整理的Java移位运算符:<<,>>,>>>的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。