Java位運算左移右移詳解:原碼反碼補(bǔ)碼與無符號右移的區(qū)別
為什么沒有無符號左移呢?
在計算機(jī)中,位運算中左移跟符號沒有關(guān)系的,因為最高位就是符號位。
例如8位的byte中最高位如果是1那就表示負(fù)數(shù)。如果是左移一位,那么最高位就會丟掉,最低位補(bǔ)0。
例如:1111 1111 << 1 就會變成 1111 1110。因此,不僅是Java,任何語言都沒有無符號左移運算符。
位操作操作的是原碼、反碼還是補(bǔ)碼?
原碼、反碼和補(bǔ)碼都是用來表示數(shù)字的編碼方式。
- 原碼就是符號位加上真值的絕對值,即用第一位表示符號,其余位表示值。例如,如果是8位二進(jìn)制,那么+1的原碼為0000 0001,-1的原碼為1000 00011。
- 反碼的表示方法是:正數(shù)的反碼是其本身;負(fù)數(shù)的反碼是在其原碼的基礎(chǔ)上,符號位不變,其余各個位取反。例如,+1的反碼為0000 0001,-1的反碼為1111 11101。
- 補(bǔ)碼的表示方法是:正數(shù)的補(bǔ)碼就是其本身;負(fù)數(shù)的補(bǔ)碼是在其原碼的基礎(chǔ)上,符號位不變,其余各位取反,最后+1。例如,+1的補(bǔ)碼為0000 0001,-1的補(bǔ)碼為1111 11111。
計算機(jī)內(nèi)部使用補(bǔ)碼來存儲數(shù)字。這樣做可以簡化計算機(jī)底層電路設(shè)計,并且可以多表示一個最低數(shù)。例如,在8位二進(jìn)制中,使用原碼或反碼表示時范圍為[-127, +127],而使用補(bǔ)碼表示時范圍為[-128, +127]。
左移 <<
將一個數(shù)對應(yīng)的二進(jìn)制表示整體左移,不考慮符號位,左邊超出的部分舍棄,右邊補(bǔ)零。
正數(shù)
以數(shù)字10為例,二進(jìn)制表示為
00000000 00000000 00000000 00001010
第一位為符號位,0表示正數(shù),1表示負(fù)數(shù)。左移1位之后為
00000000 00000000 00000000 00010100
十進(jìn)制表示為20,相當(dāng)于乘以2。HashMap擴(kuò)容時將新容量增加為原來容量的兩倍,就是使用左移實現(xiàn)的。
負(fù)數(shù)
以負(fù)數(shù)-10為例,二進(jìn)制表示為
1111 1111 1111 1111 1111 1111 1111 0110
左移1位結(jié)果為
1111 1111 1111 1111 1111 1111 11110 1100
十進(jìn)制為-20,也是相當(dāng)于乘以2。
右移 >>
將一個數(shù)對應(yīng)的二進(jìn)制表示整體右移,考慮符號位,左邊的用原有符號位補(bǔ)充,右邊超出的部分舍棄。
正數(shù)
以10為例
00000000 00000000 00000000 00001010
右移1位
00000000 00000000 00000000 00000101
十進(jìn)制表示為5,相當(dāng)于除以2。ArrayList擴(kuò)容時將新容量增加為原來的1.5倍,就是使用右移實現(xiàn)的。
負(fù)數(shù)
以負(fù)數(shù)-10為例
1111 1111 1111 1111 1111 1111 1111 0110
右移1位
1111 1111 1111 1111 1111 1111 1111 1011
十進(jìn)制表示為-5,也是相當(dāng)于除以2。
無符號右移 >>>
將一個數(shù)的二進(jìn)制表示整體右移,不考慮符號位,左邊部分總是以0填充,右邊部分舍棄。
正數(shù)
和上面的右移一致。
負(fù)數(shù)
以-10為例
1111 1111 1111 1111 1111 1111 1111 0110
無符號右移1位
01111 1111 1111 1111 1111 1111 1111 1011
十進(jìn)制表示為2147483643。HashMap中在求一個數(shù)最接近的2的N次冪時使用到了無符號右移。
超過32位的左移會怎樣?
如果一個int型數(shù)字左移超過32位,如33位,相當(dāng)于左移1位,右移、無符號右移同理。
a << n == a << (n % 32)
位移是一個取模的過程
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
在springboot項目中同時接收文件和多個參數(shù)的方法總結(jié)
在開發(fā)接口中,遇到了需要同時接收文件和多個參數(shù)的情況,可以有多種方式實現(xiàn)文件和參數(shù)的同時接收,文中給大家介紹了兩種實現(xiàn)方法,感興趣的同學(xué)跟著小編一起來看看吧2023-08-08
SpringBoot集成JWT無狀態(tài)身份認(rèn)證的方案詳解
本文介紹了如何在SpringBoot項目中集成JWT實現(xiàn)無狀態(tài)身份認(rèn)證,JWT由Header、Payload和Signature三部分組成,通過添加JJWT依賴,創(chuàng)建JWT工具類和認(rèn)證攔截器,實現(xiàn)前后端的交互流程,需要注意安全性、性能優(yōu)化和常見問題,感興趣的朋友跟隨小編一起看看吧2025-11-11

