如何(便携)在C/C++中获取DBL_EPSILON

veh*_*zzz 13 c c++

我在Linux(AS 3)上使用GCC 3.4并试图弄清楚DBL_EPSILON,或者至少是一个不错的近似值.我怎样才能以编程方式获得它?

sbi*_*sbi 31

在C++中它是std::numeric_limits<double>::epsilon().

  • 头文件是<limits> (12认同)

Ste*_*sop 28

它应该在"float.h"中.这是可移植的,它是C和C++标准的一部分(虽然在C++中被弃用 - 使用<cfloat>或者sbi的答案是"保证"前向兼容性).

如果你没有它,那么由于你的双打是IEEE 64位,你可以从其他人的float.h中偷取这个值.这是我发现的第一个:

http://opensource.apple.com/source/gcc/gcc-937.2/float.h

#define DBL_EPSILON 2.2204460492503131e-16

该值看起来对我而言,但如果您想确定您的编译器,您可以检查 (1.0 + DBL_EPSILON) != 1.0 && (1.0 + DBL_EPSILON/2) == 1.0

编辑:我不太确定你的"程序化"是什么意思.它是一个标准常量,你不应该计算它,它是在头文件中给你的实现的属性.但我猜你可以这样做.再次,假设IEEE表示或类似的东西,以便DBL_EPSILON必然是0.5的幂表示1.0的表示的最后一位精度中的1:

double getDblEpsilon(void) {
    double d = 1;
    while (1.0 + d/2 != 1.0) {
        d = d/2;
    }
    return d;
}
Run Code Online (Sandbox Code Playgroud)

要注意的是依赖于编译器的设置,中间结果可能有更高的精度比double,在这种情况下,你会得到一个较小的结果进行dDBL_EPSILON.检查编译器手册,或者找到一种方法来强制1.0 + d/2存储和重新加载到实际double对象的值,然后再将其与之比较1.0.非常粗略地说,在PC上,它取决于您的编译器是使用x86 FPU指令(更高精度)还是更新的x64浮点运算(双精度).