Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 强制PHP整数溢出_C#_Php_Integer Overflow - Fatal编程技术网

C# 强制PHP整数溢出

C# 强制PHP整数溢出,c#,php,integer-overflow,C#,Php,Integer Overflow,我们有一些整数算法,由于历史原因,它在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) ^ $

我们有一些整数算法,由于历史原因,它在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#中,我得到

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


如果有任何帮助,我们将不胜感激……

我认为这可能与PHP中的整数是无符号的32位有关,就像在C中一样,它们默认是有符号的32位

您正在玩正常31-32位范围边缘的数字

请参阅PHP手册中的其他文档:

整数的大小取决于平台,尽管通常的最大值约为20亿(即32位有符号)。PHP不支持无符号整数。整数大小可以使用常量PHP_INT_size来确定,最大值可以使用常量PHP_INT_MAX来确定,因为PHP 4.4.0和PHP 5.0.5都是如此。

这是否可行

echo (-1580033017 + -2072974554) & 0xffffffff
概括而言,您可以这样做(请原谅任何语法错误,我很久没有接触过PHP):

在内部,PHP对大多数数字使用“整数”类型。然而,这些只是到此为止:如果您将一个大整数添加到一个大整数中,PHP将看到结果太大,无法放入一个普通整数中,并将其分配给一个浮点数。然而,浮点数(float)本身的值只有这么高,在16位数字附近有一个点,PHP将完全失去绘图功能


有一个选项可以使用任意精度的数学,它支持以字符串表示的任意大小和精度的数字。请参阅此处的更多信息:

检查您的PHP版本号-我相信不同版本的PHP对长整数的支持可能不同,您可能会得到不同的结果。我相信在最后一个PHP5版本中有一个带有长整数的bug

在PHP5.2.0版本中,答案与C#中的答案完全相同

1617621783

利用上面的确切功能

您可以使用phpinfo()命令轻松查找您的版本号

$x1 = -1580033017; 
$x2 = -2072974554; 
$x3 = -1170476976 ; 
$x4 = -1007518822;
echo f($x1, $x2, $x3, $x4);

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

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

1) 这完全取决于机器运行在哪个平台上,哪个版本的PHP,是否运行了Suhosin加固的PHP,以及编译了多少位(32位或64位)。6台机器的行为符合我的预期(这实际上是错误的,至少根据他们的文档是错误的),3台机器的行为符合我仍然无法解释的方式,3台机器的行为符合intval命令在文档中的说明

2) 当INT>PHP_INT_MAX(不是INT&0xffffffff)时,Intval应该返回PHP_INT_MAX,但这只发生在PHP4和PHP5的某些版本上。当int>PHP\u int\u MAX时,不同版本的PHP返回不同的值

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

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

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

解决方案

无论如何,我需要一个能够在所有这些平台上工作的解决方案,并且不依赖于使用特定Max int编译的特定版本的PHP的怪癖。因此,我可以使用以下跨PHP thirtyTwoBitIntval函数:

function thirtyTwoBitIntval($value)
{
    if ($value < -2147483648)
    {
        return -(-($value) & 0xffffffff);
    }
    elseif ($value > 2147483647)
    {
        return ($value & 0xffffffff);
    }
    return $value;
}
函数thirtytwobitinval($value)
{
如果($value<-2147483648)
{
返回-($value)和0xffffffff);
}
elseif($value>2147483647)
{
返回($value&0xffffffff);
}
返回$value;
}
评论


我确实认为PHP的设计者应该说Int是32位的Int,不管它是在32位、64位还是128位的机器上运行(比如dotnetclr),并且没有根据PHP编译器使用的位数将其随机上转换为浮点。

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

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

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

    return $value;
}

我想你指的是PHP_INT_MAX,不是PHP_MAX_INT。
<?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";
?>
Php max int: 2147483647
The Val: -3653007571
Intval of the val: -2147483648
And of the val: -2147483648
Php max int: 2147483647
The Val: -3653007571
Intval of the val: -641959725
And of the val: -641959725
Php max int: 2147483647
The Val: -3653007571
Intval of the val: -3653007571
And of the val: -641959725
function thirtyTwoBitIntval($value)
{
    if ($value < -2147483648)
    {
        return -(-($value) & 0xffffffff);
    }
    elseif ($value > 2147483647)
    {
        return ($value & 0xffffffff);
    }
    return $value;
}
function intval32bits($value)
{
    $value = ($value & 0xFFFFFFFF);

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

    return $value;
}