【PHP】php位運算及其高級應用


     

我們之前學過邏輯與(&&)      條件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 之外的所有錯誤信息 。

 


免責聲明!

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



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