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

Vig*_*ond 9 php hex negate

有一些奇怪的行为,我想知道是否有人可以为我清理.

看看这个

$hex = 0x80008000;

print_r(decbin(intval($hex)) . '<br/>');
print_r(decbin($hex));
Run Code Online (Sandbox Code Playgroud)

输出

10000000000000001000000000000000
10000000000000001000000000000000
Run Code Online (Sandbox Code Playgroud)

正如所料.

$hex = 0x80008000;

print_r(decbin(~intval($hex)) . '<br/>');
print_r(decbin(~$hex));
Run Code Online (Sandbox Code Playgroud)

输出

1111111111111110111111111111111
1111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)

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

Vig*_*ond 0

我想在这里尝试一下我自己的问题。

是的,这是 32 位/64 位的区别。

在32位系统中,浮点类型必须占用两个内存空间才能获得所需的64位。Php 使用双精度(参见http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers

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

在第二个示例中,我们在使用 decbin 之前使用非按位运算符。这里先翻转双内存空间双精度float中的位,然后再转换为int。给我们一些与我们期望不同的东西。

事实上,如果我们将负数放在 intval() 中,如下所示:

$hex = 0x80008000;

print_r(decbin(intval(~$hex)) . '<br/>');
print_r(decbin(~$hex));
Run Code Online (Sandbox Code Playgroud)

我们得到

1111111111111111111111111111111
1111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)

作为输出。

我还不够好,无法用数学来证明这一点(可以借助本文http://en.wikipedia.org/wiki/Double_ precision来解决)。不过也许等我有时间了-_-

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