微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在PHP中计算机器epsilon的最佳方法?

如何解决在PHP中计算机器epsilon的最佳方法?

PHP中不使用内置常量PHP_FLOAT_EPSILON来直接直接计算机器epsilon(浮点舍入误差)的最佳/最正确方法是什么?目前,我已经设法研究了两种方式:“标准”和渐近地接近epsilon:

    // Standard way
    $x=1.0;
    $dx=2.0; 
    while (($x/=$dx)+1.0!=1.0); 
    echo "EPSILON : $x".",DEFINED/CALC : ".round(PHP_FLOAT_EPSILON/$x)."x\n";

    // Asymptotically approaching
    $x=1.0;
    $dx=2.0; 
    while (($x/=$dx)+1.0!=1.0) $dx/=1.0+10**-5;
    echo "EPSILON : $x".",DEFINED/CALC : ".round(PHP_FLOAT_EPSILON/$x)."x\n";

问题是,他们给出的答案有不同的错误

EPSILON : 1.1102230246252E-16,DEFINED/CALC : 2x
EPSILON : 5.6311222663283E-17,DEFINED/CALC : 4x

因此标准给出ε= 1 /2ε 0 ,其他算法给出ε= 1 /4ε 0 。我不确定应该如何正确计算ε。

解决方法

由于@EricPostpischil,导致错误的主要原因是打印了x+1=1的x的第一个值,而不是我应该打印x+1≠1的x的最后一个值。固定代码:

// Standard way
$x=1.0;
$dx=2.0; 
while (true) {
  $px = $x;
  $x/=$dx;
  if ($x+1.0==1.0) 
    break;
} 
printf ("ε = $x ≈ %.1f ε₀ \n",$px/PHP_FLOAT_EPSILON);

// Asymptotically approaching
$x=1.0;
$dx=2.0; 
while (true) {
  $px = $x;
  $x/=$dx;
  $dx/=1.0+10**-5;
  if ($x+1.0==1.0) 
    break;
} 
printf ("ε = $x ≈ %.1f ε₀ \n",$px/PHP_FLOAT_EPSILON);

报告=>

ε= 1.1102230246252E-16≈1.0ε₀
ε= 5.6311222663283E-17≈0.5ε₀

这已经足够好了,因为第一标准案例报告epsilon与PHP文档中的相同。至于第二种算法,这可能是由于四舍五入问题造成的,并且可以用不同的方式解释。即如果±ε将您带至下一个可表示的浮点数,则表示误差为半epsilon,因为任何大于| 0.5ε₀|的变化。将四舍五入到下一个可表示的数字。就像物理学家计数测量误差一样。假设您的标尺的最小测量单位为1毫米。然后在当前读数上加上±0.5 mm并四舍五入,将使您到达标尺上的下一个可表示的读数。因此,有人说实际测量误差为0.5毫米,而有人说是1毫米,取决于定义。一样。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。