PHP中十六进制的否定,有趣的行为

PHP中十六进制的否定,有趣的行为,php,hex,negate,Php,Hex,Negate,有一些奇怪的行为我在想是否有人能帮我澄清一下 看看 $hex = 0x80008000; print_r(decbin(intval($hex)) . '<br/>'); print_r(decbin($hex)); 正如所料 但是 当$hex被否定时,为什么中间位不切换?可能是这样一种情况: 从php按位运算符页面 可以使用NOT或补码运算符(~)和负二进制数 你可能会感到困惑 ~2=-3,因为按位使用公式~x=-x-1 十进制数的补数是该数减去1的反数 注意:下面的示例仅使用

有一些奇怪的行为我在想是否有人能帮我澄清一下

看看

$hex = 0x80008000;

print_r(decbin(intval($hex)) . '<br/>');
print_r(decbin($hex));
正如所料

但是


$hex
被否定时,为什么中间位不切换?

可能是这样一种情况:

从php按位运算符页面

可以使用NOT或补码运算符(~)和负二进制数 你可能会感到困惑

~2=-3,因为按位使用公式~x=-x-1 十进制数的补数是该数减去1的反数

注意:下面的示例仅使用4位,但实际上是PHP 使用32位

将负十进制数(即:-3)转换为二进制需要3 步骤:1)将十进制数的正数转换为 二进制(即:3=0011)2)翻转位(即:0011变为1100)3)相加 1(即:1100+0001=1101)

您可能想知道1101=-3是如何实现的。PHP使用这种方法 “2的补码”表示负二进制数。如果最左边的 位为1,则二进制数为负数,然后翻转位 并添加1。如果它是0,那么它是正的,你不必这样做 任何东西所以0010将是一个正的2。如果是1101,则为负值 然后你翻转位得到0010。加1,得到0011,等于 -三,


我想试试我自己的问题

是的,这是一个32位/64位的差异

在32位系统中,浮点类型必须占用两个内存空间才能获得所需的64位。Php使用双精度(请参阅)

$hex的计算结果为浮点类型。Intval和decbin函数将其转换为int类型(上面的第一个示例)

在第二个示例中,我们在使用decbin之前使用not位运算符。这将首先翻转两个内存空间中的位双精度浮点,然后转换为int second。给我们一些不同于我们期望的东西

实际上,如果我们将否定放在intval()的内部,如下所示:

作为输出

我还不足以用数学证明这一点(这可以通过本文的帮助解决)。但也许等我有时间的时候-_-


我认为了解数字在计算机中的表示方式非常重要,这样我们就可以理解这样的异常情况,而不是称之为bug。

您使用的是什么版本的PHP?第二个例子在5.3.6上对我有效,我运行的是5.3.8,问题存在。可能与这个错误有关。PHP只是一种有缺陷的语言。顺便说一句,我在OSXLion上用suhosin运行5.3.8,你的代码运行得很好。(尽管是64位)PHP一直在吸引用户:)只要
print\r(~$hex)
print\r(~intval($hex))
就可以得到什么?我认为这与问题无关。根据我的理解,
intval($hex)
应该完全等同于
$hex
,所以我希望
~intval($hex)==~$hex
。是的,我这里没有转换任何东西,只是用二进制格式表示数字。
10000000000000001000000000000000
10000000000000001000000000000000
$hex = 0x80008000;

print_r(decbin(~intval($hex)) . '<br/>');
print_r(decbin(~$hex));
1111111111111110111111111111111
1111111111111111111111111111111
$hex = 0x80008000;

print_r(decbin(intval(~$hex)) . '<br/>');
print_r(decbin(~$hex));
1111111111111111111111111111111
1111111111111111111111111111111