Java位操作快速指南 (Dev Genius)

banq發表於2021-03-16

位操作是對資料位進行操作的直接操作,並且是FAANG招聘人員目前測試的一項重要的最佳化技能。但是,該主題涉及大量數學知識,在非大學電腦科學領域很少涉及。
今天,我們將為您提供有關位操作的教程,並探討一些常見的面試問題的動手實踐。
 
什麼是位操作?
位操作是對位序列(計算機中最小的資料形式)進行邏輯運算以獲得所需結果的過程。位操作具有恆定的時間複雜度和並行處理,這意味著它在所有系統上都非常有效。
大多數程式語言都會讓您處理抽象,例如物件或變數,而不是它們所代表的位。但是,在某些情況下需要直接位操作以提高效能並減少錯誤。
位操作需要對二進位制和二進位制轉換有深入的瞭解。
以下是一些需要位操作的任務示例:
  • 低階裝置控制
  • 錯誤檢測和糾正演算法
  • 資料壓縮
  • 加密演算法
  • 最佳化

例如,看一下算術和位處理方法之間的區別,以找到RGB值的綠色部分:

//算術
(RGB / 256)%256
//位
(rgb >> 8)&0xFF

儘管兩者都做同樣的事情,但是第二種方法要快得多,因為它直接在記憶體中而不是透過抽象級別起作用。
我們將在本文後面的(>>和&)中探討這些運算子各自的作用。
 

按位操作和編碼面試
在進行程式設計面試時,尤其是在FAANG公司中,位操作也是一個常見的話題。這些是面試者希望您對位,基本的位運算子有基本的瞭解,並且通常瞭解位操作背後的思維過程。
掌握了這些知識就可以證明您是一名全面的開發人員,同時瞭解電腦科學的特定工具和基礎。
如果您要申請一個可與嵌入式系統或其他低階系統一起使用的角色,則會遇到更多問題。簡而言之,您的角色越接近機器級別,您將遇到的位操作問題就越多。
準備位操作問題的最佳方法是練習使用每個按位運算子,然後再進行二進位制到十進位制的轉換。
 

按位運算子
按位運算採用一個或多個位模式或二進位制數字,並在位級別上對其進行操作。從本質上講,它們是我們操縱位以實現操作的工具。
算術運算對人類可讀的值(1+2)進行運算時,按位運算子可直接操縱低階資料。
好處

  • 它們是快速而簡單的動作。
  • 它們由處理器直接支援。
  • 它們用於操縱值以進行比較和計算。
  • 與算術運算相比,按位運算非常簡單且速度更快。

讓我們快速看一下每個主要的Bitwise運算子及其用法。
 

AND運算子
AND(&)是一個二進位制運算子,用於比較兩個相等長度的運算元。運算元從其可讀形式轉換為二進位制表示形式。對於每個位,該操作都會檢查跨兩個運算元的兩個位是否都是1。如果是,則將答案中的該位設定為1。否則,將相應的結果位設定為0.
實際上,它會將每個位乘以另一個運算元中的相應位。將任何東西乘以0結果是0,與任何0位的AND比較將得出結果0。

  • 如果兩個輸入位為1,則輸出為1。
  • 在所有其他情況下,其值為0,例如:
  • 1 & 0 =>得出0。
  • 0 & 1 =>得出0。
  • 0 & 0 =>得出0。


0101(十進位制5)
AND 0011(十進位制3)
0 * 0 = 0
1 * 0 = 0
0 * 1 = 0
1 * 1 = 1
Therefore:
= 0001 (decimal 1)


這種操作可用於確定是將特定位設定為(1)還是將其清除(0)。它還用於清除暫存器的選定位,其中每個位代表一個單獨的布林狀態。

class AndOperation {
    public static void main( String args[] ) {
        int x = 12;
        int y = 10;
        System.out.println("Bitwise AND of (" + x + " , " + y + ") is: " + (x & y)); // yields to 8
    }
}


OR運算子
OR運算子(|)是一個二進位制運算子,它採用兩個等長的運算元,但以與AND相反的方式比較它們;如果對應的一位是1,答案是1。否則,答案將是0。換句話說,如果給定的輸入之一為1,則按位或運算將返回“ 1” 。

  • 如果有兩個輸入位0,則輸出為0。
  • 在其他所有情況下為1。例如:
  • 1 | 0 =>得出1。
  • 0 | 1 =>得出1。
  • 1 | 1 =>得出1。

a = 12 
b = 10 
--------------------------------- 
a(二進位制):0000 0000 0000 1100 
b(二進位制) :0000 0000 0000 1010 
--------------------------------- 
a | b:0000 0000 0000 1110 


這通常用作解決其他問題的臨時邏輯步驟:

class OROperation {
    private static int helper(int x, int y) {
        return x | y;
    }
    public static void main(String[] args) {
        int x = 12;
        int y = 10;
        System.out.println("Bitwise OR of " + x + ", " + y + " is: " + helper(x, y)); // yields to 14
    }
}

 

NOT運算子
NOT(~)或有時稱為按位補碼運算子,是一元操作,它接受單個輸入並將其二進位制表示形式的每個位交換為相反的值。
 

異或運算子
按位XOR運算(^)是“ Exclusive-Or”的縮寫,是一種二進位制運算子,它接受兩個輸入自變數並比較每個對應的位。如果這些位相反,在該位的位置有一個結果1,如果它們匹配,則返回0。

  • 1 ^ 1 =>得出0。
  • 0 ^ 0 =>得出0。
  • 1 ^ 0 =>得出1。
  • 0 ^ 1 =>得出1。

案例:

a = 12
b = 10
--------------------------------------
a in binary : 0000 0000 0000 1100
b in binary : 0000 0000 0000 1010
--------------------------------------
a ^ b       : 0000 0000 0000 0110
--------------------------------------


XOR用於反轉暫存器中選定的單個位或處理表示布林狀態的位模式。
XOR有時也用於將登錄檔的值設定為零,因為與兩個相同輸入的XOR總是會產生0。

class XOROperation {
    public static void main( String args[] ) {
        int x = 12;
        int y = 10;
        System.out.println("Bitwise XOR of (x , y) is : " + (x ^ y)); // yields to 6
    }
}


(據調查,異或邏輯在高階程式設計中很少應用到,但是在人們語言交流中經常存在。)
 

左右移位運算子
位元移位是按位操作,其中一個位序列的順序被移動到有效地進行數學運算。移位將數字的二進位制表示形式中的每個數字向左或向右移動第二個運算元指定的多個空格。
這些運算子可以應用於整數型別,例如int,long,short,byte,或char。

有三種型別的班次:

  • 左移: <<是左移運算子,可滿足邏輯和算術移位的需求。
  • 算術/有符號右移: >>是算術(或有符號)右移運算子。
  • 邏輯/無符號右移: >>>是邏輯(或無符號)右移運算子。


class LeftShift { 
    private static int helper(int number,int i){
        返回數字<< i; //將'number'乘以2 ^ i倍。
    } 
    public static void main(String [] args){ 
        int number = 100; 
        System.out.println(number +“向左移動1個位置,產生為” + helper(number,1))); 
        System.out.println(number +“向左移動2個位置,產生為” + helper(number,2));
        System.out.println(number +“向左移動3個位置,生成為” + helper(number,3));
        System.out.println(number +“向左移動4個位置,產生為” + helper(number,4));
    } 
}

使用右移,您可以進行算術(>>)或邏輯(>>)移位。
區別在於算術移位保持相同的最高有效位(MSB)或符號位,即最左位,它確定一個數字是正數還是負數。

1011 0101 >> 1 = **1**101 1010

公式: x >> y = x/(2^y)
另一方面,邏輯移位只是將所有內容移至右側,並用0代替MSB 。

1011 0101 >>> 1 = 0101 1010

公式: a >>> b = a/(2^b)
 

相關文章