有一些奇怪的行为我想知道是否有人可以为我清理。
检查出来
$hex = 0x80008000;
print_r(decbin(intval($hex)) . '<br/>');
print_r(decbin($hex));
输出
10000000000000001000000000000000
10000000000000001000000000000000
正如所料。
但是
$hex = 0x80008000;
print_r(decbin(~intval($hex)) . '<br/>');
print_r(decbin(~$hex));
输出
1111111111111110111111111111111
1111111111111111111111111111111
为什么在$hex
被否定时中间位不会切换?
答案 0 :(得分:0)
在这里给出我自己的问题。
是的,这是一个32位/ 64位的差异。
在32位系统中,float类型必须占用两个内存空间才能获得所需的64位。 Php使用双精度(见http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers)
$ hex计算为float类型。 Intval和decbin函数将其转换为int类型(上面的第一个示例)
在第二个例子中,我们在使用decbin之前使用非按位运算符。这将首先翻转双内存空间双精度浮点中的位,然后转换为int秒。给我们一些不同于我们预期的东西。
实际上,如果我们将intval()中的否定置于其中:
$hex = 0x80008000;
print_r(decbin(intval(~$hex)) . '<br/>');
print_r(decbin(~$hex));
我们得到了
1111111111111111111111111111111
1111111111111111111111111111111
作为输出。
我还不够用数学来证明这一点(可以在本文http://en.wikipedia.org/wiki/Double_precision的帮助下弄清楚)。但也许我以后有时间-_-
我认为了解如何在计算机中表示数字非常重要,这样我们就可以理解这样的异常,而不是将它们称为错误。
答案 1 :(得分:-1)
可能属于这个案例:
从php按位运算符页面http://us3.php.net/manual/en/language.operators.bitwise.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的补码”来呈现负二进制数。如果最左边 bit是1然后二进制数是负数,你翻转位 并添加1.如果为0则为正,您不必这样做 任何东西。因此,0010将是积极的2.如果是1101,则为负 然后翻转位以获得0010.添加1并获得等于的0011 -3。