【发布时间】:2012-02-05 18:56:23
【问题描述】:
为什么这段代码返回 -1 ?
$a = 0; 回声~$a;不应该恢复位吗?
【问题讨论】:
-
确实如此。在二进制恭维中,所有 1 的位域为 -1。 en.wikipedia.org/wiki/Two%27s_complement
标签: php
为什么这段代码返回 -1 ?
$a = 0; 回声~$a;不应该恢复位吗?
【问题讨论】:
标签: php
如果你设置一个二进制补码整数的所有位,那么你得到 -1。
让我用一个使用二进制补码的(非常小的)两位有符号整数来说明:
00 → 0
01 → 1
10 → −2
11 → −1
这只是从 0 开始计数,从 1 溢出到 -2 并以 -1 结束。如您所见,如果清除所有位会得到 0,如果将它们全部设置,则会得到 -1(不管整数有多宽)。
(请注意,使用 BASIC 的人已经知道这一点,因为没有布尔运算符,并且按位运算符也可以正常工作,只是 True 是 -1 而不是 1。)
【讨论】:
AndAlso 和 OrElse 以及布尔类型。
这个零实际上由 32 个零位表示,因为 PHP 整数类型是 32 位有符号整数,而不是单个位:
0000 0000 0000 0000 0000 0000 0000 0000
所以按位不翻转所有,导致-1的two's complement(最左边的一个代表符号):
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
再加 1
1010 +
1
-----
1011
这个 1011 被存储在 $val 中。
同理,$val=0; 00 被存储
~$val => 11 等于 -2 在 2 的补码形式中
最后,如果你仔细观察,你可能会问,
那么我怎么能代表 11 呢?因为它的二进制值是 1011,与 2 的 comp 中的 -5 的值冲突?
答案在于用于表示数字的位数。
如果有 n 位,则以 2 的形式表示,那么您只能表示来自
的值-2^(n-1) to 2^(n-1) -1 ;
【讨论】: