当前位置:  开发笔记 > 编程语言 > 正文

强制PHP整数溢出

如何解决《强制PHP整数溢出》经验,为你挑选了2个好方法。

我们有一些整数算术,由于历史原因,它必须在PHP上使用与在一些静态类型语言中相同的算法.自从我们上次升级PHP以来,溢出整数的行为已经改变.基本上我们使用以下公式:

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

但是,即使有转换:

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

我仍然以完全错误的数字结束......

例如,使用$ x1 = -1580033017,$ x2 = -2072974554,$ x3 = -1170476976)和$ x4 = -1007518822,我最终得到PHP中的-30512150和C#中的1617621783.

只是加在一起$ x1和$ x2我无法得到正确的答案:

在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?)

任何帮助,将不胜感激...



1> Kris Erickso..:

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

1)它完全依赖于运行机器的平台之间的交叉,PHP的哪个版本,无论是否运行Suhosin Hardened PHP,以及编译了多少位(32或64).6台机器按照我的预期行为(实际上是错误的,至少根据他们的文档错误)和3台机器的行为方式仍然无法解释,3台机器的行为符合intval命令所说的文档.

2)当int> PHP_MAX_INT(不是int和0xffffffff)时,Intval应返回PHP_MAX_INT,但这只发生在某些版本的PHP4和PHP5上.当int> PHP_MAX_INT时,不同版本的PHP返回不同的值.

3)以下代码可以返回3个不同的结果(见1):


它可以返回(对于Intval来说似乎是正确的,但对于&0xffffff来说是错误的)

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

它可以返回(这与intval的PHP文档相矛盾):

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

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

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

无论如何,我需要一个适用于所有这些平台的解决方案,而不是依赖于使用特定Max int编译的特定PHP版本的怪癖.因此,我使用以下交叉PHP threeTwoBitIntval函数:

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),并且没有随机上转换为a float取决于PHP编译器的位数.


我认为您的意思是PHP_INT_MAX,而不是PHP_MAX_INT。

2> 小智..:

如果你想在32位和64位平台上有32位intval的100%工作解决方案,那么我建议你使用以下解决方案:

function intval32bits($value)
{
    $value = ($value & 0xFFFFFFFF);

    if ($value & 0x80000000)
        $value = -((~$value & 0xFFFFFFFF) + 1);

    return $value;
}

推荐阅读
重庆制造漫画社
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有