• 位运算符


    位运算一览表

    符号 示例 含义
    & $a & $b 按位与。将 $a 和 $b 中都为 1 的位设为 1
    | $a | $b 按位或。将 $a 和 $b 中任何一个为 1 的位设为 1
    ^ $a ^ $c 按位异或。将 $a 和 $b 中相同位不一致的位设为 1
    ~$a ~$a 按位取反。将 $a 为 1 的位设为 0,为 0 的位设为 1
    << $a << $c 左移。将 $a 的位向 移动 $b 次
    >> $d >> $b 左移。将 $a 的位向 移动 $b 次

    & 运算符

    按位与。相同为 1,不同为 0

    $a = 1; // 0001
    $b = 2; // 0010
    echo $a & $b; // 0000
    

    按位比较,相同位得1,不同位得 0。由于 1 和 2 的二进制数中每个位都不相同,所以结果为: 0000,也就是 0。

    | 运算符

    按位或。有 1 为 1,无 1 为 0

    $a = 1; // 0001
    $b = 3; // 0011
    echo $a | $b; // 0011
    

    按位比较,相同位得 0 ,不同位 得 1,所以结果为: 0011,也就是 3。

    ^ 运算符

    按位异或。相同为 0,不同为 1

    $a = 1; // 0001
    $b = 3; // 0011
    echo $a ^ $b; // 0010
    

    按位比较,相同位得 0 ,不同位 得 1,所以结果为: 0010,也就是 2。

    ~ 运算符

    按位取反。1 取 0,0 取 1

    $a = 1; // 0000 0000 0000 0000 0000 0000 0000 0001
    $a1 = ~$a;
    echo $a1; // -2。 
    

    这个运算符相比较其它位运算符要复杂一些。我们知道,大多数编程语言中,最高位是符号位,那么,32 位操作系统下,PHP 整数的最大值是:

    0111 1111 1111 1111 1111 1111 1111 1111 = 2147483647

    因此,当对 1 进行按位取反后,得到

    $A1 = 1111 1111 1111 1111 1111 1111 1111 1110

    符号位为 1,即为 负数。在计算机中,负数以其对应绝对值的补码形式表达。也就是说,$a1 的补码是 $A1,则

    反码 = 补码 - 1 = 1111 1111 1111 1111 1111 1111 1111 1101

    那么 $a1 对应的整数就是:

    原码 = 反码各位取反 = 0000 0000 0000 0000 0000 0000 0000 0010 = -2;

    << 运算符

    各位向左移动,末尾补 0

    $a = 2; // 0000 0000 0000 0000 0000 0000 0000 0010
    $a1 = $a << 3;
    echo $a1; // 16
    

    32 位系统下,一个整数用 32 位表示。当位数向左移动,舍去多余的位数,末尾补 0 ,则得到 $a1 为:

    0000 0000 0000 0000 0000 0000 0001 0000 = 16

    因此

    $a << $b = $a^($b+1) // $a 的 ($b + 1) 次方

    左移运算符有一个比较有趣的地方,当一个数向左移动超过计算机指定整数位时,就会出现不符合我们上述总结的原数平方规则的情况。比如 2 在 64 位系统下,向左移动 62、63、64 位:

    echo 2 >> 61 // 4611686018427387904
    echo 2 >> 62 // -9223372036854775808
    echo 2 >> 63 // 0
    echo 2 >> 64 // 0
    

    有兴趣的朋友可以列出对应二进制数,推演下计算过程。

    >> 运算符

    各位向右移动,前面补 0

    $a = 8; // 0000 0000 0000 0000 0000 0000 0000 1000
    $a1 = $a << 3;
    echo $a1; // 16
    

    左移和右移运算符“误区”

    关于左移和右移运算符,很多朋友可能会看到这样的总结:

    左移平方,右移开方

    其实严格来说,这只针对值为 2 的正整数次幂的整数有效。当不是 2 的正整数次幂时,比如:

    $a = 9; // 0000 0000 0000 0000 0000 0000 0000 1001
    $a1 = $a >> 1;
    echo $a1; // 4
    

    所以,遇到左移和右移运算符时,要实际情况实际分析,不能一味的按照别人的总结走。

  • 相关阅读:
    scala学习笔记:理解stream和view
    scala学习笔记:变量声明中的模式
    scala学习笔记:理解并行集合par
    快速了解Scala技术栈
    scala学习笔记:控制抽象
    scala中的call-by-name和call-by-value
    scala学习笔记:各种奇怪的写法
    scala学习笔记:match与unapply()
    scala学习笔记:无参函数
    scala学习笔记:函数与方法
  • 原文地址:https://www.cnblogs.com/BeiGuo-FengGuang/p/9835203.html
Copyright © 2020-2023  润新知