我编写了这样一个代码来查找网格步骤(两个相邻机器之间的差异--可表示的数字,机器epsilon最小机器可表示数之间的差异大于1和1)。这个程序有多正确?
#include <stdio.h>
int main(void)
{
long double x,eps=1.0,a;
scanf("%Le",&x);
if(x>=1.8446744e+19) eps=x;
do
{
a=eps;
eps/=2.0;
}
while( x+eps>x);
printf("Grid step: %Le",(long double)a);
return 0;
}发布于 2021-04-11 21:37:45
有很多事情我建议你看看。
一个是double和long double在VisualC++中没有区别,但这是次要的事情。不过,值得知道的是,您正在获得64位IEEE二进制浮点格式。
请阅读埃里克·波斯特皮奇尔的评论。您要寻找的步骤始终是2的幂,但它可能大于、小于或等于1。您可以从1开始使用两个while循环。第一个步骤将该步骤减半,直到将该步骤添加到原始数字中,使其保持不变。
long double eps = 1.0;
while (original + eps != original)
eps *= 0.5;乘以0.5与除以2完全相同,在大多数机器上只有更快。
第二个循环将使步骤加倍,直到将其添加到原始循环确实会产生影响。与上述模式相同,将!=更改为==,将0.5更改为2.0。第二个循环将始终运行至少一次,如果只是为了退出对eps的最后一次更改,并获得2的力量,这确实是有意义的。
一个需要注意的边缘情况:如果原始值为0,那么在第一个循环期间,该步骤将向下流动到0。处理此问题的最简单方法是包含<float.h>并测试原始值为零。如果是,返回LDBL_MIN作为第一个循环之前的结果。
https://stackoverflow.com/questions/67049584
复制相似问题