5

转移到生产环境时,我的代码出现问题,因为生产服务器是 32 位,而我的开发机器是 64 位(我正在运行 Kubuntu 12.04 64 位)。我的问题是。是否可以在不安装 23 位版本的 PHP 的情况下强制 int 为 32 位?那个或允许我选择最大 int 值的库

4

3 回答 3

10

整数是该平台上指针的大小。(32 位 PHP --> 32 位整数。64 位 PHP --> 64 位整数)。

请注意,当整数运算溢出时,变量变为浮点数。PHP 文档很好地解释了这一切。

我不确定您在代码中所做的事情会导致您关心整数的大小。但是,如果您只关心值的 32 位,则始终可以屏蔽低 32 位:

$val = $something & 0xFFFFFFFF;
于 2013-03-21T20:34:38.190 回答
3
$r = $r & 0xFFFFFFFF;
if ($r & 0x80000000)
{
    $r = $r & ~0x80000000;
    $r = -2147483648 + $r;
}
于 2019-03-09T15:51:15.637 回答
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 个零”进行与运算:如果这是真的,意味着至少(最多)一个 1,这再次意味着:“在 32 位世界中,这是一个负数”,在这种情况下,我们还需要告诉 PHP 这是一个负数,因为 64 位 $r 变量的最左边的位仍然是 0,PHP 仍然认为是一个正数。

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

$r = $r & ~0x80000000;

~0x80000000 确实可以重写为 0xFFFFFFFF7FFFFFFF:32 个,1 个零,31 个。

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

您现在应该明白这一点:

$r = -2147483648 + $r;

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

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

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

于 2021-08-12T14:48:47.093 回答