力PHP整数溢出 [英] Force PHP integer overflow

查看:140
本文介绍了力PHP整数溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一些整数运算由于历史原因,有工作同样在PHP,因为它在几个静态类型语言一样。自从我们上次升级PHP的整数溢出的行为发生了变化。基本上,我们使用的是下面的公式:

We have some integer arithmetic which for historical reasons has to work the same on PHP as it does in a few statically typed languages. Since we last upgraded PHP the behavior for overflowing integers has changed. Basically we are using following formula:

function f($x1, $x2, $x3, $x4)
{
   return (($x1 + $x2) ^ $x3) + $x4;
}

然而,即使转换:

However, even with conversions:

function f($x1, $x2, $x3, $x4)
{
   return intval(intval(intval($x1 + $x2) ^ $x3) + $x4);
}

我仍然完全错误的数量结束了...

I am still ending up with the completely wrong number...

例如,以$ X1 = -1580033017,$ X2 = -2072974554,$ X3 = -1170476976)和$ X4 = -1007518822,我结束了-30512150在PHP和1617621783在C#。

For example, with $x1 = -1580033017, $x2 = -2072974554, $x3 = -1170476976) and $x4 = -1007518822, I end up with -30512150 in PHP and 1617621783 in C#.

只是相加$ x1和$ X2我不能得到正确的答案:

Just adding together $x1 and $x2 I cannot get the right answer:

在C#中,我得到

(-1580033017 + -2072974554) = 641959725

在PHP:

intval(intval(-1580033017) + intval(-2072974554)) = -2147483648

这是相同的:

intval(-1580033017 + -2072974554) = -2147483648

我不介意写IntegerOverflowAdd的功能什么的,但我不能完全弄清楚(-1580033017 + -2072974554)如何等于641959725.(我承认,这是-2147483648 +(2 * 2 ^ 31),但-2147483648 + 2 ^ 31是-1505523923比Int.Min大,从而为什么你添加2 * 2 ^ 31,而不是2 ^ 31?)

I don't mind writing a "IntegerOverflowAdd" function or something, but I can't quite figure out how (-1580033017 + -2072974554) equals 641959725. (I do recognize that it is -2147483648 + (2 * 2^31), but -2147483648 + 2^31 is -1505523923 which is greater than Int.Min so why is do you add 2*2^31 and not 2^31?)

任何帮助将是AP preciated ...

Any help would be appreciated...

推荐答案

所以,我解决了这个问题,并发现了很多关于PHP(至少在它的方式处理整数溢出)。

So I solved the problem, and discovered a lot about PHP (at least in the way it handles Integer overflow).

1),它完全依赖于哪个平台的机器上运行一个十字架,PHP的版本,它是否有硬化了Suhosin PHP中运行,它是多少位编译(32或64)。 6机表现根据什么INTVAL命令说,它确实在我预料的方式(这实际上是错误的,至少错根据他们的文档)和3台机器在某种程度上我还是无法解释的表现,以及3台机器的表现文档。

1) It completely depended on a cross between which platform the machine was running on, which version of PHP, whether or not it had Suhosin Hardened PHP running, and how many bits it was compiled for (32 or 64). 6 machines behaved the way I expected (which was actually wrong, at least wrong according to their documentation) and 3 machines behaved in a way I still can't explain, and 3 machines behaved according to what the intval command says it does in the documentation.

2)INTVAL应该返回PHP_MAX_INT时int>的PHP_MAX_INT(不是int&安培;为0xffffffff),但这只发生在PHP4和PHP5的一些版本。不同版本的PHP返回不同的值时int>的PHP_MAX_INT。

2) Intval is supposed to return PHP_MAX_INT when int > PHP_MAX_INT (not int & 0xffffffff), but this only happens on some versions of PHP4 and PHP5. Different versions of PHP return different values when int > PHP_MAX_INT.

3)以下code可以返回3不同的结果(参见图1):

3) The following code can return 3 different results (see 1):

<?php
echo "Php max int: ".PHP_INT_MAX."\n";
echo "The Val: ".(-1580033017 + -2072974554)."\n";
echo "Intval of the val: ".intval(-3653007571)."\n";
echo "And 0xffffffff of the val: ".(-3653007571 & 0xffffffff)."\n";
?>

它可以返回(这似乎是正确的,但INTVAL错误的&安培; 0XFFFFFF)

It can return (which appears to be right for Intval but wrong for & 0xffffff)

Php max int: 2147483647
The Val: -3653007571
Intval of the val: -2147483648
And of the val: -2147483648

和它可以返回(这违背了INTVAL PHP文档):

And it can return (which contradicts the PHP documentation for intval):

Php max int: 2147483647
The Val: -3653007571
Intval of the val: -641959725
And of the val: -641959725

在64位机器返回(这是正确的):

And on 64 Bit machines it returns (which is correct):

Php max int: 2147483647
The Val: -3653007571
Intval of the val: -3653007571
And of the val: -641959725

解决方案

总之,我需要一个解决方案,能够在所有这些平台上工作,而不是依赖于与特定最大INT编译PHP的特定版本的怪癖。因此,我凸轮与下面的跨PHP thirtyTwoBitIntval功能:

Anyhow, I needed a solution that would work on all these platforms, and not be dependent upon quirks of a particular version of PHP compiled with a particular Max int. Thus I cam up with the following cross-PHP thirtyTwoBitIntval function:

function thirtyTwoBitIntval($value)
{
    if ($value < -2147483648)
    {
        return -(-($value) & 0xffffffff);
    }
    elseif ($value > 2147483647)
    {
        return ($value & 0xffffffff);
    }
    return $value;
}

注释

我认为PHP的设计者应该说一个Int是一个32位的int不管它是32或64或128位机(如DOTNET的CLR为例)上运行,并没有随机变频它以一个浮动取决于位的数量,PHP是在编译器。

I do think the designers of PHP should have said an Int is a 32 Bit Int no matter whether it is running on a 32 or 64 or 128 bit machine (like the DotNet CLR for example), and didn't randomly upconvert it to a float depending on the number of Bits that PHP is compiler under.

这篇关于力PHP整数溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆