在php的运算符体系中,~是按位取反运算符,它的作用是对操作数的每一个二进制位进行取反操作,也就是把二进制位中的0变成1,1变成0。这个运算符和逻辑取反运算符!不同,它是针对二进制位层面的操作,而非针对整个布尔值的判断。

~运算符的基本运算规则
php中整型数据在内存中以二进制补码形式存储,~运算符会对整型操作数的所有二进制位执行取反操作,得到的结果也是整型。对于有符号整型,取反后的最高位符号位也会被取反,因此正数取反后通常会变成负数,负数取反后通常会变成正数。
我们可以通过简单的代码示例来验证这个规则,首先看一个正整数取反的例子:
<?php // 定义正整数5,二进制为 00000000 00000000 00000000 00000101(32位系统为例) $num = 5; $result = ~$num; // 输出取反后的结果 echo $result; // 输出-6 ?>
为什么5取反之后是-6呢?我们拆解一下运算过程:5的32位二进制补码是00000000 00000000 00000000 00000101,按位取反后变成11111111 11111111 11111111 11111010,这个结果的最高位是1,代表负数,其对应的原码是10000000 00000000 00000000 00000110,也就是十进制的-6。
负整数取反的示例
负整数取反后会得到对应的正整数,我们来看下面的代码:
<?php // 定义负整数-3 $num = -3; $result = ~$num; echo $result; // 输出2 ?>
-3的32位二进制补码是11111111 11111111 11111111 11111101,按位取反后变成00000000 00000000 00000000 00000010,也就是十进制的2,符合我们之前的运算规则。
~运算符的常见使用场景
~运算符在实际开发中有几个典型的使用场景:
- 快速计算某个数的相反数减1:对于任意整数n,~n的结果等于-n-1,这个特性可以用来简化部分运算逻辑。
- 位掩码操作:当需要反转某个二进制掩码的位状态时,可以使用~运算符快速实现,比如关闭某个权限位时,可以用原掩码和取反后的权限位做按位与操作。
- 配合其他位运算符实现复杂的位逻辑:比如和<<、>>、&、|等运算符结合,完成对二进制位的灵活控制。
使用~运算符的注意事项
在使用~运算符时,需要注意以下几点:
- ~运算符只适用于整型数据,如果对浮点型使用~运算符,php会先将其强制转换为整型再运算,可能导致不符合预期的结果。
- 不同系统的整型位数可能不同,32位系统和64位系统的整型二进制位数不同,取反后的结果也会有差异,跨环境开发时需要注意这个细节。
- 不要将~运算符和逻辑取反运算符!混淆,!运算符是将非0值转为false,0值转为true,而~是针对二进制位的逐位取反,二者的运算逻辑完全不同。
和其他位运算符结合的示例
下面展示一个~运算符和按位与运算符&结合使用的例子,实现关闭某个特定权限位的功能:
<?php // 定义权限掩码,假设第2位(从0开始计数)代表删除权限,1表示有该权限 $permission = 0b00000111; // 二进制111,有读、写、删除三个权限 // 定义删除权限的位掩码 $deleteMask = 0b00000100; // 二进制100,对应第2位 // 要关闭删除权限,需要用原掩码和取反后的删除掩码做按位与 $newPermission = $permission & ~$deleteMask; echo decbin($newPermission); // 输出11,也就是二进制00000011,删除权限被关闭 ?>
这个例子中,~$deleteMask得到11111011,和原权限掩码00000111做按位与后,第2位变成0,其他位保持不变,就实现了关闭删除权限的需求。