目錄
參考文章:
https://blog.csdn.net/is_zhoufeng/article/details/8112199
一、<< :左移運算符
說明:將運算符左邊的對象向左移動運算符右邊指定的位數(在低位補0)
通俗含義:num << 1,相當於num乘以2,依次數字遞增,乘以2的平方(不嚴謹)
例如:
2 << 1 //4 移了一位2*2
2 << 2 //8 移了兩位 2*2*2
2 << 3 //16 移了三位 2*2*2*2
二、>> :右移運算符
說明:如果值爲正,則在高位補0,如果值爲負,則在高位補1.
通俗含義:num >> 1,相當於num除以2,依次數字遞增,除以2的平方(不嚴謹)
例如:
16 >> 1 //8 移了一位 16/2
16 >> 2 //4 移了兩位 16/2/2
16 >> 3 //2 移了三位 16/2/2/2
三、>>> :無符號右移
說明:忽略符號位,高位都以0補齊
含義:無符號右移運算符>>> 結果總是正數或者0
爲什麼只對正數有意義,對負數沒有什麼算術意義,只有邏輯意義:
因爲如果一個數位負數,按照現實中數學常識,除以或乘一個負數都是負數,但在程序中都是正數顯示
爲什麼只是對32位和64位的值有意義 ?
例如:
System.out.println(-1024 >> 4); //-64
System.out.println(-1024 >>> 4); //268435392
System.out.println(1024 >>> 24); //0
引申:
與(&)、非(~)、或(|)、 從電路的角度理解
“門”是這樣的一種電路:它規定各個輸入信號之間滿足某種邏輯關係時,纔有信號輸出。
從邏輯關係看,門電路的輸入端或輸出端只有兩種狀態,無信號以“0”表示,有信號以“1”表示。
產生:通常有下列三種門電路:與門、或門、非門(反相器)
0爲假,1爲真 =====》
true ——> 1
false ——> 0
四、& :與運算
說明;符號兩邊都爲true,結果纔是true,否則爲false;對於數字,可將數字轉換爲2進制形式去理解,採用同位 與 操作即可得出結果。
聯想:在與運算中兩個開關是串聯的,如果我們要開燈,需要兩個開關都打開燈纔會打開。
例如:
true&true=true
true&false=false
false&false=false
2&3=2 即:0010&0011=0010 (從高位到低位,依次做與操作)
五、| :或運算
說明:符號兩邊只有有一個爲true,則結果爲true,否則爲false;對於數字,可將數字轉換爲2進制形式去理解,採用同位 或 操作即可得出結果。
聯想:在或運算中兩個開關是並聯的,即一個開關開,則燈開。
例如:
true|true=true
true|false=true
false|true=true
false|false=false
2|3=3 即:0010|0011=0011 (從高位到低位,依次做或操作)
六、~ :非運算
聯想:非門輸出與輸入相反,即取反運算
例如:
!true=false
!false=true
System.out.println(~2);//-3
System.out.println(~-2);//1
七、^ :異或運算
說明:相同爲0,不同爲1;對於數字,可將數字轉換爲2進制形式去理解,採用同位 異或 操作即可得出結果。
含義:異或是一種基於二進制的位運算,用符號XOR或者 ^ 表示,其運算法則是對運算符兩側數的每一個二進制位,同值取0,異值取1。
重要性質:
自反性:A XOR B XOR B = A xor 0 = A
即對給定的數A,用同樣的運算因子(B)作兩次異或運算後仍得到A本身
不進位加法:如1+1=0,,0+0=0,1+0=1。
實際應用:
利用自反性,可以獲得許多有趣的應用。 例如,所有的程序教科書都會向初學者指出,要交換兩個變量的值,必須要引入一箇中間變量。但如果使用異或,就可以節約一個變量的存儲空間: 設有A,B兩個變量,存儲的值分別爲a,b,則以下三行表達式將互換他們的值 表達式 (值) :
A=A XOR B (a XOR b)
B=B XOR A (b XOR a XOR b = a)
A=A XOR B (a XOR b XOR a = b)
類似地,該運算還可以應用在加密,數據傳輸,校驗等等許多領域。
常規測試:
2^3=1,即0010^0011=0001
true^true=false
false^false=false
true^false=true
5^2=7 即:0101^0010=0111 (從高位到低位,依次做異或操作)
拓展問題:
一:從計算速度上講,移位運算要比算術運算快?
參考:https://blog.csdn.net/fyilun/article/details/45168253
CPU角度:
因爲移位指令佔2個機器週期,而乘除法指令佔4個機器週期。
因爲移位指令不需要涉及到邏輯運算.
常規一條指令被拆分的步驟
IF ID EX MEM WB UP
取指、譯碼、執行、訪存、寫回、更新
移位指令:取指 、寫回(寫)
乘除法指令:取指、譯碼、執行、寫回(一次邏輯運算和一次寫)
從硬件上看,移位對硬件更容易實現,所以會用移位,移一位就乘2,這種乘法當然考慮移位了。
實際應用角度,JVM的自主優化:
對於乘法和以及%運算,JVM一定會優化,這些是不需要程序員去考慮的,直接去用*/%即可。
對於除法,因爲上述問題,確實是位移更快些。不過通常還是考慮使用位運算:
例如JVM源碼:
java.util.Arrays.binarySearch:
int low = fromIndex;
int high = toIndex - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
int midVal = a[mid];
if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
解析:(low + high) >>> 1代替(low + high) /2是非常正確的,首先是因爲數組下標肯定不會是負數,另一方面如果low + high大於int最大值(溢出變爲負數了)時,只有>>>1能保證結果正確。
二:二進制的起源
中國的《易經》以爻、卦來表示天地和萬物,其中爻是最基本的元素,爻分陰爻(用“--”表示)和陽爻(用“—”表示)兩種,陰爻和陽爻的不同排列就是卦象,一個卦象稱爲一卦,一卦由六爻組成一卦就是一個整體。
世界萬物中最基本的要素有8種,分別是天、地、雷、風、水、火、山和澤,他們分別用八卦表示,即乾、坤、震、坎、離、艮、兌,八卦互相搭配又得六十四卦,用來表示各種自然現象和人事現象。
我們對比二進制的組成:二進制的位用0,1表示,3位二進制可組合成8種狀態,即可表示爲0,1,...,7這8個數,而2個3位二進制組合,即變爲6位二進制數,即:2=64,即64種狀態。
萊布尼茲是第一個認識到二進制記數法重要性的人,並系統地提出了二進制數的運算法則。二進制對200多年後計算機的發展產生了深遠的影響。他於1716年發表了《論中國的哲學》一文,
還設計了一臺可以完成數碼計算的機器。並進行了二進制的推廣。
參考:
https://zhidao.baidu.com/question/1177745006240062179.html
聯想到
我們爲什麼使用二進制去作爲基本元素?
核心:兩個狀態的系統容易實現 、運算法則簡單、可進行邏輯運算。
運算規則簡單:節省設備。人們知道,具有兩種穩定狀態的元件(如晶體管的導通和截止,繼電器的接通和斷開,電脈衝電平的高低等)容易找到,而要找到具有10種穩定狀態的元件來對應十進制的10個數就困難了
適合邏輯運算:邏輯代數是邏輯運算的理論依據,二進制只有兩個數碼,正好與邏輯代數中的“真”和“假”相吻合
容易實現:二進制在物理上最易實現存儲,通過磁極的取向、表面的凹凸、光照的有無等來記錄。
日常發車:
程序員的工作是相對孤獨的,如何平衡呢?看下圖:
圖片等