C 中的机器Epsilon计算误差

Machine Epsilon Calculation Error in C++

本文关键字:计算 误差 Epsilon 机器      更新时间:2023-10-16

我正在尝试找到机器Epsilon的精度和错误。不使用std :: numeric_limits。我的教授y = 1-x/2^n,n> 1给了我以下公式。我假设y是机器epsilon,x为1.0,n应该是精度。

这是我的标题文件macepsfloat.hpp:

class MacEpsFloat
{
public:
  int precision(int n);
private:
  float e = 1.0; //error
  float x = 1.0; //variable
  float y = 0.0; //variable
  int prec = 0;
 };

这是我的macepsfloat.cpp文件

int MacEpsFloat::precision(int n)
{
    y = 1 - (x/(1<<n));
    if (y == 1.0)
    {
        prec = n-1;
    }
    else
    {
        float error = std::abs(e - y);
        std::cout << "Error: " << error << std::endl;
        ++n;
        precision(n);
    }
    return prec;
}

这是main.cpp

#include <iostream>
#include "macEpsFloat.hpp"

int main()
{
    MacEpsFloat a;
    std::cout << "Precision Float: " << a.precision(1) << std::endl;
    std::cout << std::endl;
}

可变y设置等于1.0,设置E等于1.0,n设置为等于1。

我将获得以下输出:

error: 0.5
error: 0.25
error: 0.125
error: 0.0625
error: 0.03125
error: 0.015625
error: 0.0078125
error: 0.00390625
error: 0.00195312
error: 0.000976562
error: 0.000488281
error: 0.000244141
error: 0.00012207
error: 6.10352e-05
error: 3.05176e-05
error: 1.52588e-05
error: 7.62939e-06
error: 3.8147e-06
error: 1.90735e-06
error: 9.53674e-07
error: 4.76837e-07
error: 2.38419e-07
error: 1.19209e-07
error: 5.96046e-08
Precision Float: 24

在Wiki上有2个浮子答案。第一个是1.19209E-07,精度为23,另一个是5.96046e-08,精度为24。

我在那里看到两个答案,所以我知道我在正确的轨道上。但是,我不明白为什么我的递归算法再一次将问题划分。我相信我要寻找的答案是5.96046e-08,或1.19209E-07如果我将其乘以2。但是,我不确定我的代码如何再执行一次。

我遇到的另一个问题是,由于任何原因,该代码与双打无法使用。所以我想知道为什么这样。将其扔进时循环并查看是否有任何变化,更好吗?还是我对机器Epsilon的公式错误?

任何帮助将不胜感激。

编辑:添加了编译的代码。

编辑2:我解决了我的初始问题,仍在计算错误,我只是将代码列入其他语句中,现在它可以计算出浮动点。但是,当我将所有类型的双倍更改为双倍时,它会出现故障,我不知道为什么会这样做。

我找到了问题的答案。

我更改了我的功能,以计算其他语句内部的错误。这样,它会给我当前的错误而不是之后。

我用双变量解决了SEG故障,因为我没有意识到(1&lt;&lt; n)仅由于我的机器的大小或实际体系结构而只能移动32次。因此,在递归的32次迭代后,它将抛出随机数,最终除以零,从而导致分割故障。现在的代码看起来像这样:

int MacEpsFloat::precision(int n)
{
    y = 1 - (x/(std::pow(2,n)));
    if (y == 1.0)
    {
        prec = n-1;
    }
    else
    {
        double error = std::abs(e - y);
        std::cout << "Error: " << error << std::endl;
        ++n;
        precision(n);
    }
    return prec;
}

我没有意识到我只能在远处移动。感谢您提供帮助的每个人!