PHP浮动错误:PHP挂起数值

时间:2011-01-05 15:10:26

标签: php floating-point numeric

我刚刚阅读了一篇关于某些浮点数上挂着php的有趣文章,请参阅The RegisterExploring Binary

我从未明确使用浮点数,我使用number_format()清理输入并显示价格。

另外,据我所知,来自示例表单的所有输入都是字符串,直到我告诉他们,所以我认为这个问题不会影响我。

我是对的,还是我需要检查我的服务器上的Wordpress和Squirrelmail安装示例,看看他们是否投了任何东西浮动?或者更好的是grep我的服务器上float的所有php文件?

8 个答案:

答案 0 :(得分:5)

缓解问题的方法:

  1. 使用现代CPU。大多数现代的64位CPU都是免疫的(我实际上很难找到允许重现它的主机,因为它们倾向于使用更现代的硬件)。亚马逊虚拟机似乎也具有免疫力。
  2. 升级您的PHP版本 - 5.3.5和5.2.17一旦发布(可能今天)包括修复。
  3. 在CFLAGS中使用-ffloat-store进行构建(会降低代码速度)。
  4. 手动将patch应用于您的代码并重建PHP。
  5. 在许多字符串 - >数字转换方案中,引擎使用float代码zend_strtod可能无效。

    P.S。这段代码btw是标准的BSD库strtod代码,不是PHP特有的。因此,使用此代码的其他项目也可能会受到影响。

答案 1 :(得分:4)

来自hackernews

  

由于IA-32而发生此问题   80位浮点运算。该   简单修复:添加“-ffloat-store”标志   到你的CFLAGS。

     

有问题   函数zend_strtod似乎在解析   尾数(2.225 ... 011部分)和   指数(-308份)分开,   c取代;计算m * 10 ^ e的近似值   并相继改善   近似直到错误变为   小于0.5ulp。问题是   这个特殊的数字导致了   无限循环(即迭代确实如此)   完全不改善错误)   80位FP,但不在64位FP中。   由于x86-64一般使用SSE2   指令集(64位FP)   而不是弃用的x87   没有这个问题。

答案 2 :(得分:3)

作为快速解决方法,您可以扫描输入数组:

foreach(array("_GET","_POST","_REQUEST","_COOKIES") as $G) {
    if (in_array('2.2250738585072011e-308', $$G)) {
         header("Status: 422 Unprocessable Entity");
         exit;
    }
}

如果您不在输入变量中使用子数组,这就足够了。它可以工作,因为它将float保存为字符串,输入数组保存字符串,in_array也在字符串上下文中运行。

但我没有考虑是否有其他有关该值的陈述。到目前为止,这是唯一已知的工作,但可能会有更多。因此,更可取的是更新:|

答案 3 :(得分:2)

正如marcog所说,这是x87数学的浮点运算错误。如果您想了解更多相关信息,请查看GCC错误Link

答案 4 :(得分:1)

搜索显式的float-casts对你没有帮助 - 在php中,变量被视为它的用途。小例子:

$mystring = "123.45"; //mystring is a string here
$myvalue = $mystring * 4; // mystring is a float here
                          // and there's no explicit float-cast

正如您所看到的:升级/修复您的php-installation是避免死机的唯一方法。

编辑到你的评论:

漂浮真的不那么容易。即使是简单的数字,如0.7或0.8,也无法准确存储,因此在经过一些计算后,你可能会发现0.8为0.799999999789 ......甚至更多的这种情况,只是时间问题才会出现问题。 / p>

仅作为示例(如果您是Windows用户):

  1. 打开windows-calculator
  2. 计算4的sqare-root(应为2)
  3. 从结果中得出2(应该是0但是......哇哇;))
  4. 这个bug在Windows计算器中,因为......永远 - 它表明即使是大公司也可以使用浮动失败,但计算器不会杀死你的系统 - 如果这样的错误可以杀死你的系统(比如这个php-bug),你必须升级/修复它,禁止它。

答案 5 :(得分:1)

仅仅搜索float是不够的,因为您正在查找显式地将变量值强制转换为float的代码,但是您将找不到任何隐式转换的实例。

$d = '2.2250738585072011e-308';
$f = float($d);

是显式转换,但代码如下:

$d = '2.2250738585072011e-308';
$f = $d + 0.1;

$d = '2.2250738585072011e-308';
if ($d == 0.5) {

我相信这个错误现在已经在最新的PHP构建代码中修复了,尽管xampp等软件包仍然受到影响。

答案 6 :(得分:0)

如果无法修补php安装,可以使用以下命令:Any problems with the following work around for php bug #53632

这只是一个临时的解决方法,直到你可以实际修补你的php安装

答案 7 :(得分:0)

为了捕获所有可能的数字符号,必须使用substring-search。

有关我们最新的解决方法,请参阅http://www.aircraft24.com/en/info/php-float-dos-quickfix.htm