如何在64位PHP安装中使用32位整数?

5

当我把代码移植到生产环境时,遇到了一个问题,因为生产服务器是32位的,而我的开发机是64位的(我运行的是Kubuntu 12.04 64位)。我的问题是:是否可以强制将int转换为32位,而不必安装PHP 32位版本?如果可以,那么是否有一个库可以让我选择最大的int值?


不行。PHP不能以那种方式控制变量。你不能将一个变量设置为“short”、“int”或“unsigned”。只有整数、字符串、对象和数组。但是,你可以安装32位版本的PHP。同时,可以安装多个独立的PHP。 - Marc B
2
你的 PHP 代码中进行了哪些操作可能需要一个 32 位的整数? - Halim Qarroum
你可以通过使用setter函数来限制int类型的值,使其不超过32位整数数字限制(2,147,483,647)。因此,如果将通用整数设置为高于该值,则可以抛出异常。当然,这并非绝对可靠。此外,它可能不会节省内存,因为PHP仍将为64位整数保留所有空间。最后一件事是创建一个表示32位整数的类,并使用链接的“char”,但这可能不会比使用64位整数带来更多好处。 - user1467267
一个简单的(int)转换。我修复了错误,但强制使用32位可以帮助进行单元测试。是的,我希望有一种不需要单独安装的方法。太遗憾了 =/ - Yohan Leafheart
3个回答

10
整数是平台上指针的大小。(32位PHP -> 32位整数。64位PHP -> 64位整数)。请注意,当整数操作溢出时,变量会变成浮点数。PHP文档 很好地解释了所有这些内容。但我不确定您在代码中做了什么会导致您关心整数的大小。然而,如果您只关心值的低32位,您可以始终屏蔽低32位。
$val = $something & 0xFFFFFFFF;

1
$val = $something & 0xFFFFFFFF; 这行代码让我开心不已,谢谢! - fnkbz
4
举个例子,在计算CRC32时,有一个案例是不使用内置的CRC32算法,就像在我的情况下我需要逐字节进行计算。这里涉及到大整数相乘,并且希望它们在64位系统上表现得像有符号的32位整数一样。 - A.Grandt

3
$r = $r & 0xFFFFFFFF;
if ($r & 0x80000000)
{
    $r = $r & ~0x80000000;
    $r = -2147483648 + $r;
}

2
请在您的代码中添加一些解释 - 它如何回答所给的问题? - Nico Haase
这个解决方案似乎也模拟了int溢出? - Olle Härstedt
$r = $r & ~0x80000000; 这部分是如何工作的?使用 ~ 对位进行取反有什么意义,然后再执行 $r = -2147483648 + $r; - tonix

0
$r = $r & 0xFFFFFFFF;
if ($r & 0x80000000)
{
    $r = $r & ~0x80000000;
    $r = -2147483648 + $r;
}

试图解释是谁请求的。

取您的$r大数变量(假设在64位上分布),并仅让最右边的32位通过。

$r = $r & 0xFFFFFFFF; //aka 0x00000000FFFFFFFF

现在,64位的$r变量有32个零和你的32位。请注意,在64位和32位表示中,惯例上最左边的位是符号位:正(0)或负(1),因此PHP现在认为64位的$r是正数。

if ($r & 0x80000000) {

"32个零,你的32位"与"32个零,1和31个零"进行AND运算:如果结果为真,则表示至少(最多)有一个1,这意味着:"在32位世界中,这是一个负数",在这种情况下,我们还需要告诉PHP这是一个负数,因为64位变量$r的最左边的大多数位仍然为0,而PHP仍然认为它是一个正数。

因此,让我们告诉PHP这实际上是一个负数并重新调整数字。第一步,将你的32位中最左边的位置设置为零,以强制其为正数。

$r = $r & ~0x80000000;

~0x80000000 实际上可以被重写为 0xFFFFFFFF7FFFFFFF:32个1,1个0,31个1。

现在你有一个正的32位数字表示在一个64位变量内,并且它是与其相关的32位负表示的补码:例如,如果一开始有64个1(十进制中的-1),此时 $r 是32个0,1个刚设置的0,31个1(十进制中的2147483647)。

现在你应该明白了:

$r = -2147483648 + $r;

最小可表示的32位数字+我们的补码正数。

此时,$r变量仍然是一个64位变量,但现在它正确地表示了您在开始时选择的32个最右位的负面性。

整个问题在于,在64位的PHP中,如果您提取最右边的32位,并用另一个64位变量填充,那么该值仍然是正数,因为64位最左边是0。相反,我们想实现的是:如果提取的32位表示负数,则使64位变量为负;如果提取的32位表示正数,则使64位变量为正。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接