• 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做参考

      0000 0000 0000 0000 0000 0000 0000 0000 
    0 000 0000 0000 0000 0000 0000 0000 1001
    

      

    将9左移一位,最高位也就是红色的0出来,然后被舍弃,低位补0如下

    0000 0000 0000 0000 0000 0000 0000 0000 
     000 0000 0000 0000 0000 0000 0000 10010
    

    计算出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右移一位,如下,由于保持符号位不变,左边第二个是空,右边第一个被移出来

       0000 0000 0000 0000 0000 0000 0000 0000 
     0 000 0000 0000 0000 0000 0000 0000 1001
    

    然后空出来的用符号位补齐,这里符号位是0,所以就用0补齐,如下

     0000 0000 0000 0000 0000 0000 0000 0000 
     00000 0000 0000 0000 0000 0000 0000 100
    
    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 之外的所有错误信息 。

  • 相关阅读:
    【读书笔记】之《把时间当做朋友》
    软件工程——五大模型
    VB中的GetUserName函数
    VB中 vbp vbw frm frx log bas 等扩展名大全
    【机房收费系统】——基本数据设定的理解
    在64位WindowsServer2012R2中安装Oracle10g第二版(10.2.0.4.0)-20160106
    Linux——vi命令详解
    使用Postman测试WebService接口
    npm和yarn的淘宝镜像添加
    yarn配置私有registry
  • 原文地址:https://www.cnblogs.com/echojson/p/12054771.html
Copyright © 2020-2023  润新知