Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/228.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
用PHP计算机器ε的最佳方法?_Php_Precision_Floating Accuracy_Epsilon - Fatal编程技术网

用PHP计算机器ε的最佳方法?

用PHP计算机器ε的最佳方法?,php,precision,floating-accuracy,epsilon,Php,Precision,Floating Accuracy,Epsilon,在PHP中直接计算机器epsilon(浮点舍入误差)的最佳/最正确方法是什么,而不是使用内置常量PHP\u FLOAT\u epsilon?目前,我研究了两种方法,“标准”和渐近逼近ε: // Standard way $x=1.0; $dx=2.0; while (($x/=$dx)+1.0!=1.0); echo "EPSILON : $x".", DEFINED/CALC : ".round(PHP_FLO

在PHP中直接计算机器epsilon(浮点舍入误差)的最佳/最正确方法是什么,而不是使用内置常量
PHP\u FLOAT\u 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";
问题是,他们给出的答案有不同的错误:

ε:1.1102230246252E-16,已定义/计算:2x

EPSILON:5.6311222663283E-17,已定义/计算:4x


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

多亏了@EricPostpischil,导致错误的主要原因是打印x的第一个值
x+1=1
,而不是打印x的最后一个值
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 ε₀


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

最好在堆栈站点上询问这个问题,可能是,也可能不是。它还可能取决于浮点格式的语言实现。在任何情况下,不仅仅是数学浮点格式的实现是计算机的东西。@RiggsFolly:不,这里涉及的问题是计算问题。特别是,舍入导致
($x/=$dx)+1.0
不等于
1.0
,即使
($x/=$dx)
小于“机器ε”(但超过一半)。这是一个计算问题,而不是一个纯粹的数学问题。如果你看到“机器ε”的定义是
1+x
不等于
1
的最小值x,那是不正确的。“机器ε”的正确定义是,它是1和下一个可表示数字之间的差。这叫美国。所以1和1+e是可表示的数字。假设x是(½u,u)中的某个数字。然后,当计算
1+x
时,结果为1+u,因为它被四舍五入,实际算术结果介于1和1+u之间,这是两个最接近的可表示值。因为它更接近1+u,所以四舍五入到1+u,这就是为什么第一个定义是错误的。第二,循环终止后,代码显示
$x
的值,这意味着它显示两个表达式相等的
$x
的第一个值,而不是显示两个表达式不相等的
$x
的最后一个值。