7

我正在尝试eps(x)在 C++ 中实现 Matlab 的功能

例如,在 Matlab 中:

>> eps(587.3888)
ans = 1.1369e-13
>> eps(single(587.3888))
ans = 6.1035e-05

但是,当我尝试在 C++ 中执行此操作时,我无法获得正确的单精度答案。

#include <limits>
#include <iostream>
#include <math.h>

#define DEBUG(x) do { std::cerr << x << std::endl; } while (0)
#define DEBUG2(x) do { std::cerr << #x << ": " << x << std::endl; } while (0)

int main() {

    float epsf = std::numeric_limits<float>::epsilon();
    DEBUG2(epsf);
    double epsd = std::numeric_limits<double>::epsilon();
    DEBUG2(epsd);

    float espxf = nextafter(float(587.3888), epsf) - float(587.3888);
    double espxd = nextafter(double(587.3888), epsd) - double(587.3888);
    DEBUG2(espxf);
    DEBUG2(espxd);

}

运行程序我得到以下输出:

$ ./a.out 
epsf: 1.19209e-07
epsd: 2.22045e-16
espxf: -1.13687e-13
espxd: -1.13687e-13

似乎由于某种原因,即使单精度和双精度的 eps 值是正确的,使用nextafter函数的输出也只输出双精度值。我的值epsxf应该是 6.1035e-05,就像在 Matlab 中一样。

有什么想法吗?

4

2 回答 2

7

如果你有 C++11 编译器,包含<cmath>和调用std::nextafter,你的代码就可以工作。

包含<math.h>和调用::nextafter调用函数的 C 版本。C 实现nextafter显然不支持重载,因此 C 提供了nextafterf单精度结果和nextafterl四精度结果。(简单地调用双精度nextafter失败float,因为参数被转换为double。)如果你没有 C++11 编译器,你可以通过调用来修复你的代码::nextafterf

于 2013-11-23T23:13:17.907 回答
3

使用库。Matlabeps在其他语言中的函数称为 ULP,表示最后的单元。根据关于ULP的维基百科文章, boost C++ 库中的以下函数可用于计算两个双精度a和之间的浮点距离b

boost::math::float_distance(a, b)

的文档float_distance这里

于 2013-11-23T23:16:11.577 回答