我們之前學過邏輯與(&&) 條件1 && 條件2 當兩邊條件同時成立時候返回1
邏輯或(||) 條件1 || 條件2 當兩邊條件只要有一個成立時候返回1
一. & 按位與
只有對應的兩個二進制位均為1時候,結果位才會是1,否則為0.
舉例: 比如9&5,其實就是1001&101 = 1,因此9&5=1
計算過程
1001 0101 --------- 0001
php代碼
echo 9&5; //1
二. | 按位或
只要對應的兩個二進制位有一個為1時,結果位就位1,否則為0。
舉例: 比如9|5,其實就是1001 | 101 = 1,因此9|5=13;
1001 0101 --------- 1101
三. ^ 按位異或
對應二進制位相異(不相同)時,結果位1,否則為0.
舉例: 比如9^5,其實就是1001^ 101 = 1,因此9^5=12
1001 0101 --------- 1100
echo 9^5; // 12
如果自己異或自己呢
1001 1001 --------- 0000
就是0
那用自己在異或0
1001 0000 --------- 1001
得到的還是自己。
根據上面分析得到如下規律
相同整數^的結果是0,比如5^5=0
多個整數相^的結果跟順序無關,比如5^6^7 = 5^7^6
任何數值跟0進行異或,結果還是等於原來的數值,比如 9^6^9 = 9^9^6 = 0^6 = 6
應用:
根據上面原理,加密算法中,可以使用使用異或運算符進行加密與解密,在二進制運算中,如果將一個明文的二進制位與密鑰進行按位“異或”運算,將得到密文,將此密文與密鑰再次進行按位“異或”運算,又可以得到明文。這樣,只需編寫一個函數便可以同時完成加密和解密兩種運算。
四. ~ 按位取反
把每個二進制位取反,它是單目運算符,只操作一個數。
舉例: ~9 把9每個二進制位取反。
~0000 0000 0000 0000 0000 0000 0000 1001 1111 1111 1111 1111 1111 1111 1111 0110 開頭第一個數是符號位 這里得出為負數
echo ~9; // -10
五. << 位運算左移
把整數的各個二進制位全部左移n位,高位要放棄,低位補0,左移n位其實就是乘以2的n次方。
由於左移位是丟棄最高位,0補最低位,所以符號位也要丟棄,左移后的結果可能會改變正負性。
舉例: <<9
下面用0做參考
將9左移一位,最高位也就是紅色的0出來,然后被舍棄,低位補0如下
計算出9左移一位后的值是
echo 9<<1; //18
在計算下
echo 9<<2; //36 相當於 9*4=18 在相當於 9*2的2次方 echo 9<<3; //72 相當於 9*6=72 在相當於 9*2的3次方 echo 9<<4; //144 相當於 9*16=144 在相當於 9*2的4次方
得出規律
9 << n = 9*2的n次方
所以可以引申計算的時候,比如 9*6 就是等於 9<<3,而且位運算比較快。
注意一點,最高位如果是1倍丟棄,后面那一位是0,所以會影響正負性的。
六. >> 位運算右移
把整數的各個二進制位全部右移n位,保持符號位不變,右移n位其實就是除以2的n次方。
為正數時,符號位為0,最高位補0。
為負數時,符號位為1,最高位是補0或者補1,這取決於編譯系統的規定。
舉例: 把9右移一位,如下,由於保持符號位不變,左邊第二個是空,右邊第一個被移出來
然后空出來的用符號位補齊,這里符號位是0,所以就用0補齊,如下
echo 9>>1; //4 echo 8>>1; //4 8右移一位也等於4
右移和左移也有規律
echo 8>>1; //4 echo 8>>2; //2 echo 8>>3; //1
得出
8>>n 等於8/2的n次方
七,利用位操作來實現變量值的互換
我們一般交換兩個變量的值都是利用一個臨時變量來存儲中間的值
$a = 10; $b =12; $temp = $a; $a = $b; $b = $temp; echo sprintf("a=%d,b=%d",$a,$b);//a=12,b=10
或者
$a = $b - $a; $b = $b - $a; $a = $b + $a; echo sprintf("a=%d,b=%d",$a,$b);//a=12,b=10
位運算 利用異或^的規則 a^b^a == a^a^b == b
$a = $a ^ $b; $b = $a ^ $b; $a = $a ^ $b; echo sprintf("a=%d,b=%d",$a,$b);//a=12,b=10
結果也是一樣的
八.利用位運算判斷奇偶性
一般用取模的方法來判斷是否是奇偶數
比如:
10%2 == 0 那么就是偶數 否則是奇數
根據查看 二進制中 最后一位如果是1那么就是奇數 ,如果是0那么就是偶數。如下:
15 的而二進制數 : 0000 1111
9 的而二進制數 : 0000 1001
14 的而二進制數 : 0000 1110
10 的而二進制數 : 0000 1010
位於運算,只有當對應的二進制數都是1的時候才是1,否則為0
$a & 1 == 1 //奇數
$a & 1 == 0 //偶數
運算符號
|
意義
|
運算對象類型
|
運算結果類型
|
實例
|
~
|
非運算
|
整型,字符型
|
整型
|
~a
|
&
|
與運算
|
a & b
|
||
|
|
或運算
|
a | b
|
||
^
|
異或運算
|
a ^ b
|
||
<<
|
位左移運算
|
a<<4
|
||
>>
|
位右移運算
|
a>>2
|
使用位運算案例:
1.兩數字求和
//兩數字相加 (不支持小數) function add($num1, $num2) { if ($num1 == 0) { return $num2; } if ($num2 == 0) { return $num1; } $XORresult = $num1 ^ $num2; $carry = ($num1 & $num2)<<1; return add($XORresult,$carry); }
echo add(3,2); //5
2.php 函數error_reporting() 設置 PHP 的報錯級別並返回當前級別。
error_reporting(E_ALL & ~E_NOTICE)
錯誤報告是按位的,先取得 E_ALL 的值(二進制)然后 再取得 E_NOTICE 的值(二進制),然后在通過 ~ 將其取反。
error_reporting(E_ALL ^ E_NOTICE);//顯示除去 E_NOTICE 之外的所有錯誤信息 。
error_reporting(E_ALL^E_WARNING^E_NOTICE);//顯示除去E_WARNING E_NOTICE 之外的所有錯誤信息 。