如何(可移植地)在 C 和 C++ 中获得 DBL_EPSILON

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1566198/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:27:18  来源:igfitidea点击:

How to (portably) get DBL_EPSILON in C and C++

c++c

提问by vehomzzz

I am using GCC 3.4 on Linux (AS 3) and trying to figure out to get DBL_EPSILON, or at least a decent approximation. How can I get it programmatically?

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

回答by sbi

In C++ it's std::numeric_limits<double>::epsilon().

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

回答by Steve Jessop

It should be in "float.h". That is portable, it's part of the C and C++ standards (albeit deprecated in C++ - use <cfloat>or sbi's answer for "guaranteed" forward compatibility).

它应该在“float.h”中。这是可移植的,它是 C 和 C++ 标准的一部分(尽管在 C++ 中已弃用 - 使用<cfloat>或 sbi 对“保证”向前兼容性的回答)。

If you don't have it, then since your doubles are IEEE 64-bit, you can just steal the value from someone else's float.h. Here's the first one I found:

如果您没有它,那么由于您的双打是 IEEE 64 位,您可以从其他人的 float.h 中窃取值。这是我找到的第一个:

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

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

#define DBL_EPSILON 2.2204460492503131e-16

#define DBL_EPSILON 2.2204460492503131e-16

The value looks about right to me, but if you want to be sure on your compiler, you could check that (1.0 + DBL_EPSILON) != 1.0 && (1.0 + DBL_EPSILON/2) == 1.0

这个值对我来说看起来很合适,但是如果你想确定你的编译器,你可以检查一下 (1.0 + DBL_EPSILON) != 1.0 && (1.0 + DBL_EPSILON/2) == 1.0

Edit: I'm not quite sure what you mean by "programmatically". It's a standard constant, you aren't supposed to calculate it, it's a property of the implementation given to you in a header file. But I guess you could do something like this. Again, assuming IEEE representation or something like it, so that DBL_EPSILON is bound to be whatever power of 0.5 represents a 1 in the last bit of precision of the representation of 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;
}

Beware that depending on compiler settings, intermediate results might have higher precision than double, in which case you'd get a smaller result for dthan DBL_EPSILON. Check your compiler manual, or find a way to force the value of 1.0 + d/2to be stored and reloaded to an actual doubleobject before you compare it to 1.0. Very roughly speaking, on PCs it depends on whether your compiler uses the x86 FPU instructions (higher precision), or newer x64 floating point ops (double precision).

请注意,根据编译器设置,中间结果可能具有比 更高的精度double,在这种情况下,您会得到d比更小的结果DBL_EPSILON。检查你的编译器手册,或找到一种方法来强制的价值1.0 + d/2存储和重新加载到一个实际的double,你把它比之前的对象1.0。粗略地说,在 PC 上,这取决于您的编译器是使用 x86 FPU 指令(更高精度)还是更新的 x64 浮点运算(双精度)。