最负数,大于-DBL_MAX

时间:2015-01-25 16:39:11

标签: c++

我代表一个“物理上不可能”的值,可以在计算机上表示最负面的值。

#include <float.h>
double physically_impossible = -DBL_MAX;

对此的测试效果很好

if( physically_impossible == -DBL_MAX )
    cout << " OK, detected impossible value";
else
    cout << " failed to detect impossible value";
cout << endl;

 OK, detected impossible value

但是,当我尝试测试一个非常小但“物理可能”的数字时,出现了可怕的错误。

double physically_impossible_plus_one = 1 - DBL_MAX;
cout << "physically_impossible " << physically_impossible << " physically_impossible_plus_one " << physically_impossible_plus_one;
if( physically_impossible < physically_impossible_plus_one )
    cout << " OK, detected impossible value plus one";
else
    cout << " failed to detect impossible value plus one";
cout << endl;

给出

physically_impossible -1.79769e+308 physically_impossible_plus_one -1.79769e+308 failed to detect impossible value plus one

正如Karoly Horvath指出的那样,由于精度有限,这失败了。我需要的是最负数,大于-DBL_MAX

(动机:我希望将物理可能数量的可用范围的最小减少划分为物理上可能和物理上不可能的数字(不是引发异常和触发断言的NAN)。)

4 个答案:

答案 0 :(得分:3)

浮点表示的精度有限。添加一个到-1.79769e + 308显然不会改变它。

这不是问题,不用担心。如果该值代表任何物理属性,那么接近DBL_MAX意味着您正在做一些可怕的错误。

答案 1 :(得分:2)

尝试使用极值来表示“虚无”并不是一个好主意,这就是为什么:根据定义,你处于浮点类型的精确界限的极限,因此你的内容非常有限可以做到这个价值。

我强烈建议使用为此目的而发明的值,例如std::numeric_limits<double>::quiet_NaN()。请注意,您将无法对其进行任何算术。

答案 2 :(得分:1)

DBL_MAX与下一个最大数字之间的差异是2的幂(因为两个尾数中的差异恰好是1)。因此,在程序启动时,您可以搜索两个p的最小功率,DBL_MAX - p != DBL_MAX-(DBL_MAX - p)将是您的最小可用值:

double p = 1.0 ;
while (DBL_MAX - p == DBL_MAX) p *= 2.0 ;
double smallest_usable_value = -(DBL_MAX - p) ;

答案 3 :(得分:0)

在没有评论我是否觉得这是一个非常好的方法......你需要添加最多 16位数的东西(实际上略小于16,因为2 53 < / sup>是9.007e + 15)小于DBL_MAX,或者你添加的任何值都是微不足道的,并且&#34;消失&#34;。

1e+292比&#34;典型&#34;小16位数。 DBL_MAX为1.7e + 308,因此任何接近该数字的数字都可以满足您的需求。概念证明:

#include <float.h>
#include <stdio.h>


int main()
{
    double pi = -DBL_MAX;
    double pi_plus = -DBL_MAX + 1e+292;

    printf("%g\n", pi);
    printf("%g\n", pi_plus);
    printf("%i\n", pi == pi_plus);

  return 0;
}

输出:

-1.79769e+308
-1.79769e+308
0

Live demo