大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 hot資訊 實例解析移位運算符

實例解析移位運算符

更新時間:2020-10-13 17:21:37 來源:動力節點 瀏覽1250次

移位操作是把數據看作二進制數,然后將其向左或向右移動若干位的運算。在Java中,移位運算符包含三種:<<左移運算符,>>帶符號右移運算符,>>>無符號右移運算符。這三種操作符都只能作用于long,int,short,byte這四種基本整形類型上和char類型上。下面我們來詳細介紹這三種移位運算符。


1.左移操作符<<

左移操作符<<是將數據轉換為二進制后,向左移動若干位,高位丟棄,低位補零。

首先我們可以利用java中的方法獲取一個數的二進制:Integer.toBinaryString(int val)。

然后我們看下面這個例子:

public static void main(String[] args) {

int a = 10;

System.out.println("左移前的二進制:"+Integer.toBinaryString(a));

a <<= 2;

System.out.println("左移后的二進制:"+Integer.toBinaryString(a));

System.out.println("左移后的十進制:"+a);

}

首先定義一個數,值為10,打印它的二進制(1010),然后進行左移操作2位。打印移位后的結果和二進制。

左移前的二進制:1010

左移后的二進制:101000

左移后的十進制:40

可以看出,將原來的二進制向左移動了兩位,后面進行了補零。40=10 * 2 * 2。所以一次左移等于將這個數擴大了兩倍。對于左移N位,就等于乘以2^n,如40=10*2^2。再來看一個負數的左移:

int b = -8;

System.out.println("左移前的二進制:" + Integer.toBinaryString(b));

b <<= 2;

System.out.println("左移后的二進制:" + Integer.toBinaryString(b));

System.out.println("左移后的十進制:" + b);

我們定義了一個負數(-8),打印出它的二進制,進行左移2位,左移后打印它的二進制,再將10進制打印出來查看。

左移前的二進制:11111111111111111111111111111000

左移后的二進制:11111111111111111111111111100000

左移后的十進制:-32

可以明顯的看出二進制向左移動了兩位,前面的位置丟棄,后面的位置補零。轉換為10進制也符合我們之前的運算:-32 = -8 * 2 *2。


2.帶符號右移操作符>>

剛才的左移中,它向左移動,高位進行了丟棄,低位進行補零。但是右移操作時有一個符號位,操作不當將造成答案與預期結果不同。

帶符號右移就是在**向右移動若干位,低位進行丟棄,高位按照符號位進行填補。**對于正數做右移操作時,高位補充0;負數進行右移時,高位補充1。

再來用例子證明一下:

public static void main(String[] args) {

int a = 1024;

System.out.println("a右移前的二進制:" + Integer.toBinaryString(a));

a >>= 4;

System.out.println("a右移后的二進制:" + Integer.toBinaryString(a));

System.out.println("a右移后的十進制:"+a);

int b = -70336;

System.out.println("b右移前的二進制:" + Integer.toBinaryString(b));

b >>= 4;

System.out.println("b右移后的二進制:" + Integer.toBinaryString(b));

System.out.println("b右移后的十進制:"+b);

}

定義了兩個變量,a=1024,然后向右移動4位。b=-70336也向右移動4位。分別將它們的移動前后二進制和十進制打印出來查看。

a右移前的二進制:10000000000

a右移后的二進制:1000000

a右移后的十進制:64

b右移前的二進制:11111111111111101110110101000000

b右移后的二進制:11111111111111111110111011010100

b右移后的十進制:-4396

a原來的二進制向右移動后,低位被丟棄,高位補充符號位也就是0。b原來的二進制向右移動后,低位被丟棄,高位補充符號位1。這也符號我們之前的運算規律:

1024 / 2^4^ =16 ;-70336/ 2^4^ = -4396。


3.無符號右移操作符>>>

剛才的帶符號右移操作符,我們在向右移動時帶著高位的符號,正數填充0,負數填充1?,F在不帶符號的右移操作符大體與右移操作符一致,只不過不再區分正負數,結果都是高位補零,低位丟棄。

再用例子來證明一下:

public static void main(String[] args) {

int a = 1024;

System.out.println("a右移前的二進制:" + Integer.toBinaryString(a));

a >>>= 4;

System.out.println("a右移后的二進制:" + Integer.toBinaryString(a));

System.out.println("a右移后的十進制:"+a);

int b = -70336;

System.out.println("b右移前的二進制:" + Integer.toBinaryString(b));

b >>>= 4;

System.out.println("b右移后的二進制:" + Integer.toBinaryString(b));

System.out.println("b右移后的十進制:"+b);

}

還是剛才帶符號右移的例子:這次我們僅僅把操作符換成無符號的右移操作符。

按照定義,其實在正數時不會有變化,因為在帶符號的右移中正數也是高位補零。只不過當值為負數時會有變化,讓我們看一下輸出是不是符合猜想。

a右移前的二進制:10000000000

a右移后的二進制:1000000

a右移后的十進制:64

b右移前的二進制:11111111111111101110110101000000

b右移后的二進制:1111111111111110111011010100

b右移后的十進制:268431060

確實正數沒有變化,驗證了我們的猜想。然后是負數,這次向右移動時高位進行了補零,低位丟棄。改變后的數值不再符合我們之前的規律。

在無符號右移中,當值為正數時,依然符合之前的規律移動一位相當于除以2。但是當值為負數時不再符合規律。

當移位的位數超過數值所占用的位數會怎么樣?

這個問題很有意思,我們剛剛都僅僅移動了2位或者4位,如果我們超過了int的位數也就是32位后會怎么樣?我們如果對一個正數左移32位,低位補零補充了32次就變成0了,就如同下面代碼所寫的一樣,最終a的結果會是什么。會變成0嗎?

public static void main(String[] args) {

int a = 10;

a <<= 32;

System.out.println(a);

}

經過我們運行后發現a的結果最終沒變還是10。我們如果改成左移33位,它的結果會變成20。那么它的運算規律會不會是當超過位數后僅僅移動對位數的余數呢?比如對int做操作,它實際是運算 位數%32次。


經過多次試驗發現答案確實就是這個猜想,當對int類型處理時,右移x位的運算為x%32位。

對其他類型也是一樣嗎?

我們剛才都是用的int類型,那么對于byte,short,char,long都一樣嗎?

事實上,Java在對byte,short,char這三種類型進行移位操作前,會將其先轉型為int類型,然后再進行位操作。由于我們有進行了重新賦值將其賦值為原來的byte類型,所以又進行了從int到byte的先下轉型,也就是截斷。我們對上面的例子進行一下修改可以更直觀的發現運行過程:

public static void main(String[] args) {

byte b = -1;

System.out.println("操作前十進制:"+b);

System.out.println("操作前二進制:"+Integer.toBinaryString(b));

System.out.println("進行無符號右移6位后的十進制:"+(b>>>6));

System.out.println("操作后二進制:"+Integer.toBinaryString(b>>>6));

}

在這里我沒有使用=進行重新賦值,而是計算完成后直接打印十進制和二進制的結果。

操作前十進制:-1

操作前二進制:11111111111111111111111111111111

進行無符號右移6位后的十進制:67108863

操作后二進制:11111111111111111111111111

從打印結果中可以明顯的看出是先轉換為int類型,然后進行位運算,位運算結束后由于重新賦值所以進行的截斷。

對于long類型,它是64位,不用先轉換。

我們不難得出結論,移位符是Java中的基本操作符,實際支持的類型只有int和long。在對byte,short,char類型進行移位操作時,都會先將其轉換為int類型再進行操作。左移<<操作符相當于乘以2。帶符號右移操作符>>相當于除以2。在Java中使用位運算符會比乘*,除/運算符更高效一些。而無符號右移符>>>在移動時高位補零,低位丟棄,在正數時仍然相當于除以2,但是在負數時結果卻是變大了(由負數變為正數)。


本文對三種移位運算符進行了詳細地講解,事實上,在講解的過程中用到我們之前學習的一些Java基礎知識,比如說Java的移位操作,以及各個進制的轉換。對于,Java零基礎的小伙伴來說,不要急于求成,學習更高難度的知識,而是應該返璞歸真,從基礎開始,打好基礎才能鑄就輝煌。


提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 老子影院午夜 | 成人亚洲精品一区 | 久久免费精品高清麻豆 | 手机福利在线 | 国产亚洲自在精品久久 | 国产香蕉98碰碰久久人人 | 亚洲成a人片在线观看www | 精品国产一区二区三区香蕉事 | 欧美三级美国一级 | 色婷婷精品大视频在线蜜桃视频 | 免费高清a毛片 | 亚洲人成毛片线播放 | 天天狠狠弄夜夜狠狠躁·太爽了 | 久久青草网站 | 日本不卡视频在线 | 成人午夜 | 亚洲国产精品67194成人 | 97成人在线视频 | 狠狠色丁香婷婷综合激情 | 色婷婷综合久久久久中文 | 久久香蕉国产线看免费 | 国产高清精品一区 | 伊人精品在线观看 | 三a大片| 国产成+人+亚洲+欧美综合 | 中文字幕日本一区波多野不卡 | 国产成人国产在线观看入口 | 日日爽日日操 | 国产91在线|亚洲 | 人人看操| 9999热视频 | 日日夜夜精品视频 | 日本三级11k影院在线 | 天堂精品在线 | 一区二区三区在线免费看 | 97在线视频免费公开观看 | 一级午夜免费视频 | 久久综合桃花网 | 国产亚洲精aa在线观看香蕉 | 毛片爱做的片 | 免费毛片播放 |