PHP(或任何其他语言)中的Bit not操作


Bit not operation in PHP(or any other language probably)

为什么此代码返回-1?

$a=0;echo ~$a;

难道不应该还原这些片段吗?

如果在2的补码整数上设置所有位,则得到−1。

让我用一个(非常小的)使用2的补码的2位有符号整数来说明:

00 →  0
01 →  1
10 → −2
11 → −1

这只是从0开始向上计数,经过从1到−2的溢出,并在−1结束。正如你所看到的,如果你清除所有的位,你得到0,如果你把它们都设置好,你得到−1(不管整数有多宽)。

(请注意,使用BASIC的人已经知道这一点,因为没有布尔运算符,而且使用位运算符也一样好,只是True是−1而不是1。)

零实际上是由32个零位表示的,因为PHP整数类型是32位有符号整数,而不是单个位:

0000 0000 0000 0000 0000 0000 0000 0000

因此,按位NOT翻转所有,导致两者的补码为-1(最左边的一个表示符号):

1111 1111 1111 1111 1111 1111 1111 1111

是的,它应该是,在二者的补数系统中,一个所有位都设置为-1的数字,由于0所有位都未设置,~$a将所有位都被设置。

因此,代码的行为与预期一致。

整数以2的互补形式存储。

这种形式可以概括如下:

1) 如果要存储的数字是正值,则将其二进制值存储为

例如$val=5;

这里$val包含5=0101//的普通二进制等价物。位数取决于具体的

2) 如果你正在存储一个数字的负数,比如-5,那么两个互补的存储

$val = -5;

这里找出了第一个2对5的赞美,即简单地说,1对5+1 的赞美

~ 0101 = 1010

tnen添加1个

  1010 + 
     1
  -----
  1011

这个1011被存储在$val中。

同样地,$val=0;00存储

~$val=>11,它等于2的互补形式中的-2

最后,如果你仔细观察,你可能会问,

那么我怎么能代表11呢?因为它的二进制值是1011,与2的comp中的-5的值冲突?

答案在于用来表示数字的位数。

在2的compliant形式中,如果有n个位,则只能表示中的值

-2^(n-1) to 2^(n-1) -1 ;