为什么此代码返回-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 ;