如何(可移植地)在 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
How to (portably) get DBL_EPSILON in C and 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 d
than DBL_EPSILON
. Check your compiler manual, or find a way to force the value of 1.0 + d/2
to be stored and reloaded to an actual double
object 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 浮点运算(双精度)。