關於java按位操作運算


<1>.在了解位移之前,先了解一下正數和負數的二進制表示形式以及關系:
舉例15和-15:

15 的原碼: 00000000 00000000 00000000 00001111 
    補碼: 11111111 11111111 11111111 11110000
                 +1 = 
-15的原碼:11111111 11111111 11111111 11110001

負數的原碼即為:正數的原碼取反,再加1。

<2>位移操作:(只針對 int類型的數據有效,java中,一個int的長度始終是32位,也就是4個字節,它操作的都是該整數的二進制數).也可以作用於以下類型,即 byte,short,char,long(當然,它們都是整數形式)。當為這四種類型是,JVM先把它們轉換成int型再進行操作。

<<     左移   
>>     右移
>>>    無符號右移

<< 和>>為數值位移,>>>為邏輯位移。【注】:Java中不存在<<<。

$1> m<<n的含義:把整數m表示的二進制數左移n位,高位移出n位都舍棄,低位補0.  (此時將會出現正數變成負數的形式) 左移
實例:
  3<<2剖析:
  3二進制形式: 00000000 00000000 00000000 00000011,按照$1的原理,得到00000000 00000000 00000000 00001100,即為12.
  
  左移使整數變為負數:
  10737418<<8
  10737418二進制表示形式:00000000 10100011 11010111 00001010,按照$1的原理,得到10100011 11010111 00001010 00000000,即為:-1546188288.

$2> m>>n的含義:把整數m表示的二進制數右移n位,m為正數,高位全部補0;m為負數,高位全部補1. 算術右移 有符號右移
實 例: 
  3>>2剖析:
  3二進制形式: 00000000 00000000 00000000 00000011,按照$2的原理,得到00000000 00000000 00000000 00000000,即為0.
  -3>>2剖析:
  -3二進制形式: 11111111 11111111 11111111 11111101,按照$2的原理,得到11111111 11111111 11111111 11111111,即為-1.

以上:每 個整數表示的二進制都是32位的,如果右移32位和右移0位的效果是一樣的。依次類推,右移32的倍數位都一樣。

備注:對於右移32位與右移0位是結果是一樣的,我一直不能夠理解。現在我只能理解為32比較特殊。相當於整體全移。與移0位相同。左移也是一樣的。

$3> m>>>n:整數m表示的二進制右移n位,不論正負數,高位都補零。 邏輯右移 無符號右移
實例: 
  3>>>2剖析:
  3二進制形式: 00000000 00000000 00000000 00000011,按照$3的原理,得到00000000 00000000 00000000 00000000,即為0.
  -3>>>2剖析:
  -3二進制形式: 11111111 11111111 11111111 11111101,按照$3的原理,得到00111111 11111111 11111111 11111111,即為1073741823.
   

【注】:對於$1,$2,$3,如果n為負數:這時JVM會先讓n對32取模,變成一個絕對值小於32的負數,然后再加上32,直到 n 變成一個正數。
實例:
   4<<-10
   4的二進制形式:00000000 00000000 00000000 00000100,-10對32取模再加上32,不用說了,得到22,則4<<-10,即相當於4<<22。
   此時按照再按照$1原理,得到00000001 00000000 00000000 00000000,得到的即為:16777216。
4<<34 :相當於 4<<2
OK, 大功告成。

綜上所述:

在不大於自身數值類型最大位數的移位時,
   m<<n即在數字沒有溢出的前提下,對於正數和負數,左移n位都相當於m乘以2的n次方.
   m>>n即相當於m除以2的n次方,得到的為整數時,即為結果。如果結果為小數,此時會出現兩種情況:(1)如果m為正數,得到的商會無條件 的舍棄小數位;(2)如果m為負數,舍棄小數部分,然后把整數部分加+1得到位移后的值。

接 下來在此說說位操作的好處,速度超快,這些都是底層的二進制機器操作指令。
  比如:a*2,

       1.jvm先為變量a分配空間;
       2.再進行a*2的操作;
      3.再把結果返回給相應的變量。

而 a<<1,和a*2一樣,它只需要一條指令即可,速度很快。當然前三種位移操作都是對2的倍數
進行操作時可用。

在hashMap擴容中使用過:左移

 

int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1;

 ArrayList擴容中使用過:右移

/**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

 

 


再 進行些許補充,談到位操作,當然還要說到四個操作符:

~(按位非),|(按位或),&(按位與),^(按位異或),

這些都是大學 計算機基礎用法,對整數的二進制形式進行操作,然后再

轉換為整數,具體操作如下。

1.~(按位非):【解義】對該整數的二進制形 式逐位取反。
    ~4:(一元操作符)
     4的二進制形式為:00000000 00000000 00000000 00000100,逐位取反后得

到:11111111 11111111 11111111 11111011,即為-5.
2.| (按位或):【解義】對兩個整數的二進制形式逐位進行邏輯或運算,原理為:1|0=1,0|0=0,1|1=1,0|1=1
等。
    4|-5:
     4的二進制形式為:00000000 00000000 00000000 00000100,
    -5的二進制形式為:11111111 11111111 11111111 11111011,
  逐位進行邏輯或運算:11111111 11111111 11111111 11111111,即得到-1.
3.&(按位與):【解義】對兩個整數的二進制形式逐位進行邏輯與 運算,原理:1|0=0,0|0=0,1&1=1;0&1=0等。  
   4&-5:
     4的二進制形式為:00000000 00000000 00000000 00000100,
    -5的二進制形式為:11111111 11111111 11111111 11111011,
  逐位進行邏輯與運算:00000000 00000000 00000000 00000000,即得到0.  

實際應用:可以把字節轉換為整 數,-64&0xFF=192,也可以用八進制的形式,-64&0377=192、

 

其實0xFF和0377都表示的是整數255、 
4.^(按 位異或):【解義】對兩個整數的二進制形式逐位進行邏輯異或運算,原理:1^1=0,1^0=1,0^1=1,0^0=0.
   4^-5:
     4的二進制形式為:00000000 00000000 00000000 00000100,
    -5的二進制形式為:11111111 11111111 11111111 11111011,
逐位進行邏輯異或運算:11111111 11111111 11111111 11111111,即得到-1. 

實際應用:按位異或可以比較兩個數字是否相等,它利用 1^1=0,0^0=0的原理。  20^20==0 

轉自:http://aokunsang.javaeye.com/blog/615658 

關於二進制一些說明: 

關於負數的二進制表示方法

今天知道了對於負數的二進制方法的表示方法:例如 -5   
第一步:首先要把5變成101的二進制形式
第二步:再者就是按位取反,(形 成前面全是1)010
第三步:在最后加1 形成:11111111 11111111 11111111 11111011
反過來如果把 最高位是1的二進制變成負的整形時
第一步:位取反,變成00000000 00000000 00000000 00000100
第二 步:在最低位加上1,形成101
第三步:形成整形5 ,在加上負號;
在java中怎么用代碼實現二進制於十進制的轉化
public int binaryInToInt(String str)
{
             int j=0,i=0;
            char c;
            for(i=0;i<str.length();i++)
             {
                      if(str.charAt(str.length()-i)=='1')
                        {
                                     j=j+exp(2*ln(str.length()-i));
                        }
 
             }
return j;

轉自:
http://blog.csdn.net/zdp5528/archive/2008/04/10/2278719.aspx

(1)正負表示方法
用字節的最高位表示:"1"表示"正","0"表示"負"

(2)計算機中數字是以哪個碼儲存的?
補碼

(3) 負數 的二進制補碼轉換成十進制的方法
1、把補碼“取反”(把二進制數的各位“1”換“0”,“0”換“1”。比如“101010”取反后為“010101”)
2、把取反后的二進制數“加1”
3、最后用常規的方法把“加1”后的二進制數轉換為十進制數

將負數轉換為二進制

詳見:https://www.cnblogs.com/lukelook/p/11274795.html

 

1.~(按位非):【解義】對該整數的二進制形 式逐位取反。
    ~4:(一元操作符)
     4的二進制形式為:00000000 00000000 00000000 00000100,逐位取反后得

到:11111111 11111111 11111111 11111011,即為-5.
2.| (按位或):【解義】對兩個整數的二進制形式逐位進行邏輯或運算,原理為:1|0=1,0|0=0,1|1=1,0|1=1
等。
    4|-5:
     4的二進制形式為:00000000 00000000 00000000 00000100,
    -5的二進制形式為:11111111 11111111 11111111 11111011,
  逐位進行邏輯或運算:11111111 11111111 11111111 11111111,即得到-1.
3.&(按位與):【解義】對兩個整數的二進制形式逐位進行邏輯與 運算,原理:1|0=0,0|0=0,1&1=1;0&1=0等。  
   4&-5:
     4的二進制形式為:00000000 00000000 00000000 00000100,
    -5的二進制形式為:11111111 11111111 11111111 11111011,
  逐位進行邏輯與運算:00000000 00000000 00000000 00000000,即得到0.  

實際應用:可以把字節轉換為整 數,-64&0xFF=192,也可以用八進制的形式,-64&0377=192、

其實0xFF和0377都表示的是整數255、 
4.^(按 位異或):【解義】對兩個整數的二進制形式逐位進行邏輯異或運算,原理:1^1=0,1^0=1,0^1=1,0^0=0.
   4^-5:
     4的二進制形式為:00000000 00000000 00000000 00000100,
    -5的二進制形式為:11111111 11111111 11111111 11111011,
逐位進行邏輯異或運算:11111111 11111111 11111111 11111111,即得到-1.

實際應用:按位異或可以比較兩個數字是否相等,它利用 1^1=0,0^0=0的原理。  20^20==0

轉自:http://aokunsang.javaeye.com/blog/615658

關於二進制一些說明:

關於負數的二進制表示方法

今天知道了對於負數的二進制方法的表示方法:例如 -5   
第一步:首先要把5變成101的二進制形式
第二步:再者就是按位取反,(形 成前面全是1)010
第三步:在最后加1 形成:11111111 11111111 11111111 11111011
反過來如果把 最高位是1的二進制變成負的整形時
第一步:位取反,變成00000000 00000000 00000000 00000100
第二 步:在最低位加上1,形成101
第三步:形成整形5 ,在加上負號;
在java中怎么用代碼實現二進制於十進制的轉化
public int binaryInToInt(String str)
{
             int j=0,i=0;
            char c;
            for(i=0;i<str.length();i++)
             {
                      if(str.charAt(str.length()-i)=='1')
                        {
                                     j=j+exp(2*ln(str.length()-i));
                        }
 
             }
return j;

轉自:
http://blog.csdn.net/zdp5528/archive/2008/04/10/2278719.aspx

(1)正負表示方法
用字節的最高位表示:"1"表示"正","0"表示"負"

(2)計算機中數字是以哪個碼儲存的?
補碼

(3) 負數 的二進制補碼轉換成十進制的方法
1、把補碼“取反”(把二進制數的各位“1”換“0”,“0”換“1”。比如“101010”取反后為“010101”)
2、把取反后的二進制數“加1”
3、最后用常規的方法把“加1”后的二進制數轉換為十進制數


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM