有一些奇怪的行为,我想知道是否有人可以为我清理.
看看这个
$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被否定时不切换?
我想在这里尝试一下我自己的问题。
是的,这是 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来解决)。不过也许等我有时间了-_-
我认为了解数字在计算机中的表示方式非常重要,这样我们就可以理解这样的异常,而不是称它们为错误。