提问人:Agnius Vasiliauskas 提问时间:10/20/2020 更新时间:10/21/2020 访问量:451
在PHP中计算机器epsilon的最佳方法?
Best way to calculate machine epsilon in PHP?
问:
在PHP中直接计算机器epsilon(浮点舍入误差)的最佳/最正确的方法是什么,而不使用内置常量?目前,我已经设法研究了两种方式,“标准”和渐近接近 epsilon :PHP_FLOAT_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。我不确定应该如何正确计算 epsilon。
答:
多亏了@EricPostpischil,错误的主要原因是打印了 x 的第一个值,而不是我应该打印 x 的最后一个值。固定代码:x+1=1
x+1≠1
// 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
ε₀
现在已经足够好了,因为第一个 -standard case- 报告 epsilon 与 PHP 文档中的相同。至于第二个算法,可能是由于舍入问题,可以有不同的解释。也就是说,如果 ±ε 让你得到下一个可表示的浮点数,那么表示误差是 epsilon 的一半,因为任何大于 |0.5 ε₀|将四舍五入到下一个可代表的数字。这类似于物理学家计算测量误差。假设您有一把最小测量单位为 1 毫米的尺子。然后将 ±0.5 毫米添加到当前读数和四舍五入将使您进入标尺上的下一个可表示读数。因此,有人说实际测量误差是 0.5 毫米,有人说是 1 毫米,这取决于定义。同样在这里。
评论
($x/=$dx)+1.0
1.0
($x/=$dx)
1+x
1
1+x
$x
$x
$x