⬛ >> versus >>> Java的位元運算有兩個很類似的右移運算子,目的是將其唯一的運算元進行往右的位元平移。 當運算元為正時,兩者結果相同,分不出來;遇負數時,兩者結果才有差異。 說明如下: 邏輯右移運算子 >>>: number >>> bits; 表示將2進位數字右移bits位元,左邊補0 算術右移運算子 >> : number >> bits; 也表示將2進位數字右移bits位元,左邊保留目前符號位元 例1: 對於負數,兩種位元右移結果的比較: >> versus >>>int n = -7; System.out.printf("n = %d (%x)\n",n,n); System.out.printf("n >> 2 = %d (%x)\n",n >> 2,n >> 2); System.out.printf("n >>> 2 = %d (%x)\n",n >>> 2, n >>> 2);
則3行輸出如下: n = -7 (fffffff9) // 二進位表示為 1111 1111 1111 1111 1111 1111 1111 1001 n >> 2 = -2 (fffffffe) // 二進位表示為 1111 1111 1111 1111 1111 1111 1111 1110 n >>> 2 = 1073741822 (3ffffffe) // 二進位表示為 0011 1111 1111 1111 1111 1111 1111 1110 其中,第一行二進位為原始數字; 第二行運算將二進位數字往右平移2位元,左邊補目前符號位元1; 第三行運算將二進位數字往右平移2位元,左邊補0 註: 須要維持正負號的右移運算可用 >> 註: 不補符號位元的右移運算可用 >>> 註: 至於左移運算子,因為右邊永遠補0,沒有其他選擇,所以只有一種 << 運算子 ⬛ & versus && as well as | versus || Java的且及或運算也各有很接近的運算子,其說明如下: 邏輯且: b = bool_1 && bool_2; // 有短路求值,遇bool_1假,不看bool_2值,一律回傳假 位元且: b = bool_1 & bool_2; // 無短路求值 n = number_1 & number_2; 邏輯或: b = bool_1 || bool_2; // 有短路求值,遇bool_1真,不看bool_2值,一律回傳真 位元或: b = bool_1 | bool_2; // 無短路求值 n = number_1 | number_2; 例2: 對於數字及布林值,兩種【且】運算的比較: & versus &&System.out.printf("true & false = %b\n", true & false); System.out.printf("true && false = %b\n", true && false); System.out.printf("1100 & 0101 = %x\n", 0b1100 & 0b0101); //System.out.printf("1100 && 0101 = %d\n", 0b1100 && 0b0101);
則3行輸出如下: true & false = false true && false = false 1100 & 0101 = 4 // 二進位表示 為0100 其中,第一行兩布林值進行【位元且】運算,只當兩布林值同時為真時才為真,故得到假; 第二行兩布林值進行【邏輯且】運算,只當兩布林值同時為真時才為真,故得到假; 第三行兩數字進行【位元且】運算,只留下兩數字同時為1的位元才為1,故得到0100=4。 另外,第四行語法不允許兩數字進行【邏輯且】運算,故註解起來。 例3: 對於數字及布林值,兩種【或】運算的比較: | versus ||System.out.printf("true | false = %b\n", true | false); System.out.printf("true || false = %b\n", true || false); System.out.printf("1100 | 0101 = %x\n", 0b1100 | 0b0101); //System.out.printf("1100 || 0101 = %d\n", 0b1100 || 0b0101);
則3行輸出如下: true | false = true true || false = true 1100 | 0101 = d // 二進位表示 為1101 其中,第一行兩布林值進行【位元或】運算,只當兩布林值同時為假時才為假,故得到真; 第二行兩布林值進行【邏輯或】運算,只當兩布林值同時為假時才為假,故得到真; 第三行兩數字進行【位元或】運算,只留下兩數字同時為0的位元才為0,故得到1101=13=d。 另外,第四行語法不允許兩數字進行【邏輯或】運算,故註解起來。 例4: 對於布林值,短路求值與否的【且】運算比較: & versus &&b = b1 = b2 = true; b = (b1=false) & (b2=false); System.out.printf("no short circuit evaluation: b:%b, b1:%b, b2:%b\n",b,b1,b2); b = b1 = b2 = true; b = (b1=false) && (b2=false); System.out.printf("use short circuit evaluation:b:%b, b1:%b, b2:%b\n",b,b1,b2);
則2行輸出如下: no short circuit evaluation: b:false, b1:false, b2:false use short circuit evaluation:b:false, b1:false, b2:true 其中,第一行輸出不作短路求值,所以b1及b2皆接收到false值; 第二行輸出有作短路求值,所以b1接收回傳false值後,不須進行b2=false運算,就可判定b為假,故b2維持true值。 例5: 對於布林值,短路求值與否的【或】運算比較: | versus ||b = b1 = b2 = false; b = (b1=true) | (b2=true); System.out.printf("no short circuit evaluation: b:%b, b1:%b, b2:%b\n",b,b1,b2); b = b1 = b2 = false; b = (b1=true) || (b2=true); System.out.printf("use short circuit evaluation:b:%b, b1:%b, b2:%b\n",b,b1,b2);
則2行輸出如下: no short circuit evaluation: b:true, b1:true, b2:true use short circuit evaluation:b:true, b1:true, b2:false 其中,第一行輸出不作短路求值,所以b1及b2皆接收到true值; 第二行輸出有作短路求值,所以b1接收回傳true值後,不須進行b2=true運算,就可判定b為真,故b2維持false值。 註: 數字的且/或運算只能用 &, | 註: 條件式或布林值的且/或運算,若須要短路求值可用 &&, || 註: 條件式或布林值的且/或運算,若不須要短路求值可維持 &, | 參考: 1.StackOverflow: Difference between >>> and >> 2.Wiki: Short Circuit Evaluation
2017年5月17日 星期三
java right shift and and/or operators in comparison
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言