9

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

看看这个

$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为什么在被否定时中间位不切换?

4

2 回答 2

0

会在这里试一试我自己的问题。

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

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

$hex 计算为浮点类型。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的帮助下弄清楚)。但也许等我有时间的时候-_-

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

于 2012-03-11T20:09:49.640 回答
-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的补码”方法来呈现负二进制数。如果最左边的位是 1,那么二进制数是负数,你翻转这些位并加 1。如果它是 0,那么它是正数,你不需要做任何事情。所以 0010 将是一个正数 2。如果是 1101,它是负数,你翻转位得到 0010。加 1,你得到 0011,等于 -3。

于 2012-03-08T20:25:28.420 回答