C ++中的机器Epsilon计算错误

时间:2017-09-03 20:47:51

标签: c++ math recursion

我试图找到Machine 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个Floats的答案。第一个是1.19209e-07,精度为23,另一个是5.96046e-08,精度为24.

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

我遇到的另一个问题是这段代码因任何原因无法使用双打。所以我想知道为什么会这样。将它抛入while循环并查看是否有任何变化是否更好?或者我对Machine Epsilon的公式有误吗?

任何帮助都将不胜感激。

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

编辑2:我解决了我的初始问题,错误仍在计算中,我只是将这段代码扔进了else语句中,现在它计算浮点就好了。但是,当我将所有类型更改为双精度数时,它会出现故障,我不知道为什么会这样做。

1 个答案:

答案 0 :(得分:0)

我找到了问题的答案。

我改变了我的函数来计算else语句中的错误。那样它会给我当前的错误,而不是之后的错误。

我用Double变量解决了Seg Fault,因为我没有意识到(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;
}

我没有意识到我到目前为止只能进行一点调整。感谢所有帮助过的人!