php的~是对整数的二进制补码表示按位取反,连符号位一起翻转,结果通常为负数;如~5得-6,~0得-1,需配合&掩码(如~$x & 0xff)限制位宽,主要用于位操作而非数学计算。

php按位取反~到底对什么取反
PHP的~是对整数的**二进制补码表示**做按位取反,不是简单地把0变1、1变0后当原码读。它会连符号位一起翻,结果几乎总是负数(除非输入是-1)。
常见错误现象:~5你以为是-5或2,实际输出是-6;~0不是-0而是-1。
- PHP用有符号32位(或64位,取决于平台)补码存储整数,
~操作的是这个完整二进制形式 - 比如
5在32位下是00000000 00000000 00000000 00000101,取反后变成11111111 11111111 11111111 11111010,按补码规则解读就是-6 - 如果真想“逻辑上”翻转低N位(比如只处理掩码),得配合
&掩码,例如~$x & 0xFF限制在8位内
什么时候该用~,什么时候不该用
按位取反在PHP里极少用于数学计算,主要出现在位掩码操作中,比如关闭某个标志位、构造掩码、与&配合实现“清零”。
使用场景:
立即学习“PHP免费学习笔记(深入)”;
- 清除某几位:比如要关掉第3位(从0开始),写
$flags & ~(1 ,而不是<code>$flags & (1 - 生成全1掩码:如
~0得到平台位宽下的全1整数(32个1或64个1),常用于初始化位集合 - 和
bindec()/decbin()混用时容易出错——它们处理的是无符号字符串,而~产出的是有符号整数,直接传给decbin()会显示负号前缀
~在不同PHP版本和平台上的表现差异
结果值取决于整数位宽,而位宽由PHP编译时决定(PHP_INT_SIZE通常是4或8字节),不是由运行时配置控制。
- 32位系统下:
~0=-1(即0xFFFFFFFF补码表示) - 64位系统下:
~0=-1(仍是-1,但二进制是64个1) - 关键点:虽然
-1看起来一样,但参与位运算时(如&),高位隐含的1会影响结果。例如~1 & 0xFFFF在32位和64位下结果一致,但~1 & 0xFFFFFFFFFF可能因高位扩展行为不同而微妙差异 - 不要依赖
~$x的具体数值,只依赖其与&、|组合后的位效果
最容易被忽略的坑:类型自动转换干扰~
~只定义在整数上。如果操作数不是int,PHP会先强制转成整数,这个过程可能静默丢失信息,导致结果完全偏离预期。
-
~"5"→ 先转成(int)"5"得5,再取反得-6;但~"abc"转成0,结果是-1 -
~null→0→-1;~[](空数组)→0→-1;这些都不是直觉能猜到的 - 浮点数会被截断:
~3.9等价于~3即-4,不是对小数部分取反 - 安全做法:显式类型断言,比如
~((int)$x),或提前校验is_int($x)
补码、位宽、隐式转换这三者叠在一起,才是~真正难搞的地方。写的时候别只看单个表达式,得盯住它前后上下文里的数据来源和类型流转。











