【问题标题】:How to (portably) get DBL_EPSILON in C and C++如何(可移植地)在 C 和 C++ 中获取 DBL_EPSILON
【发布时间】:2009-10-14 13:23:25
【问题描述】:

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

【问题讨论】:

  • 下面没有人谈论的一件很重要的事情:对 Epsilon 价值的任何定义都是无缘无故(或几乎)冒出来的赌注。我的意思是,这是为合理计算定义的合理值。计算机上实数的本质是它们不是精确值(bin vs dec)。因此,任何计算都会扩大计算值与理论值之间的差距。 Epsilon 就是针对这个差距的。如果你真的做了很多计算,你最终可能会发现这个差距大于标准的 epsilon。在计算机上使用实数时要格外小心。

标签: c++ c


【解决方案1】:

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

【讨论】:

  • 头文件为
  • 不客气。要注意的另一件事是,如果没有 epsilon,它不会引发异常。它只是悄悄地返回零。 (至少在 MSVC++ 2010 上) cout ::epsilon()
  • @JiveDadson epsilon for int 没有意义。我想这就是您期待异常的原因?
【解决方案2】:

它应该在“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;
}

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

【讨论】:

  • 如何以编程方式获取?
  • 我怀疑while ((double)(1.0 + d/2) != 1.0) { 会处理“中间结果的精度可能比double 更高”的问题。
猜你喜欢
  • 2018-10-09
  • 1970-01-01
  • 2015-04-13
  • 2023-03-05
  • 2015-02-28
  • 2015-10-08
  • 2010-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多