机器epsilon计算问题

时间:2018-02-16 15:53:56

标签: php floating-point precision

我偶然发现了机器epsilon计算结果之间的差异。 与0相比,PHP产量为4.9406564584125E-324。 而对于1,它弹出1.1102230246252E-16。

相当不同。猜猜它是PHP中默认最初设置的数据类型。

代码是:

<?php
//Machine epsilon calculation

$e = 1;
$eTmp = null;

for ($i = 0; 0 != 0 + $e; $i++){ //Changing 0 by 1 produces absolutely different result
     $e = $e/2;
    if ($e != 0) {$eTmp = $e;}
}

echo $eTmp;
//var_dump($eTmp);

?>

对两者之间的区别有何澄清? 如何通过手动分配变量或值来浮动PHP? 非常感谢你的想法!

1 个答案:

答案 0 :(得分:1)

您的PHP实现似乎使用通用的IEEE 754 64位二进制格式。在这种格式中,有限值有效地表示为符号,整数 M 小于2 53 ,整数指数 e -1074和971,包括在内。表示的值为+ M •2 e 或 - M •2 e < / em> ,根据标志。 (这种格式通常用 M 来表示,它是1到2之间的一小部分,在小数点之后有一定的位数。这些描述在数学上是等价的,只是用于不同的目的。)

鉴于此,我们可以很容易地看到0之后的下一个可表示的数字是+ 1•2 -1074 ,大约是4.94065645841246544•10 -324

在所述格式中,1可表示为+ 1•2 0 。但是,要了解可以对1进行的最小变化是什么,我们必须通过使 M 尽可能大来对其进行标准化。 1也可以用 M = 2 52 e = -52表示,得到+2 52 • 2 -52 。在这种形式中,我们可以看到通过向 M 添加1来实现大于1的下一个可表示值,mkaing数字+(2 52 +1)•2 -52

1和+之间的差异(2 52 +1)•2 -52 当然是1•2 -52 ,其中正好是2.220446049250313080847263336181640625•10 -16

请注意,在使用$eTmp缩减$e后,您的代码记录$e(如果$e = $e/2不为零),这意味着它会报告$e的第一个值} 导致更改。因此它报告1.11e-16而不是2.22e-16,这是导致更改为1的最后一个值。