浮动或双重特殊值

时间:2008-12-02 00:47:23

标签: c++ floating-point double

我有双(或浮点)变量可能是“空”,就像没有有效值一样。如何用内置类型float和double来表示这个条件?

一个选项是一个包含浮点数和布尔值的包装器,但这不起作用,因为我的库有容器存储双精度而不是表现为双精度的对象。另一个是使用NaN(std :: numeric_limits)。但我认为无法检查变量是否为NaN。

如何解决需要“特殊”浮点值来表示数字以外的其他问题?

4 个答案:

答案 0 :(得分:7)

我们通过使用NaN来做到这一点:

double d = std::numeric_limits<double>::signaling_NaN();
bool isNaN = (d != d);

与自身相等的NaN值将产生错误。这就是你测试NaN的方式,但是如果std::numeric_limits<double>::is_iec559为真,它似乎才有效(如果是,它也符合ieee754)。

在C99中,isnan中有一个名为math.h的宏,它会检查NaN值的浮点数。

答案 1 :(得分:6)

在Visual C ++中,有一个非标准_isnan(double)函数可以通过float.h导入。

在C中,您可以通过math.h导入isnan(double)功能。

在C ++中,有一个isnan(double)函数可以通过cmath导入。

正如其他人所指出的那样,使用NaN可能会带来很多麻烦。它们是一种特殊情况,必须像NULL指针一样处理。不同之处在于NaN通常不会导致核心转储和应用程序故障,但它们很难追踪。如果您决定使用NaN,请尽可能少地使用它们。过度使用NaN是一种冒犯性的编码实践。

答案 2 :(得分:2)

它不是内置类型,但我通常使用boost::optional来做这种事情。如果你绝对不能使用它,也许一个指针就可以了 - 如果指针是NULL,那么你知道结果不包含有效值。

答案 3 :(得分:1)

一个选项是一个包含浮动广告布尔值的包装器,但这不起作用,因为我的库有容器存储双打而不是表现为双打的对象。

这太遗憾了。在C ++中,创建一个自动转换为实际双(引用)属性的模板化类是微不足道的。 (或者对该问题的任何其他类型的引用。)您只需在模板化类中使用强制转换运算符。例如:运营商TYPE&amp; (){返回值;然后,您可以在通常使用双精度的任何地方使用HasValue&lt; double&gt;。

另一个将使用NaN(std :: numeric_limits)。但我认为无法检查变量是否为NaN。

litb James Schek 也注意到,C99为我们提供了isnan()。

但要小心!南数值使得数学和数学逻辑真有意思!你认为一个数字不能是NOT&gt; = foo和NOT&lt; = foo。但是对于NaN,它可以。

我在工具箱中保留一个WARN-IF-NAN(X)宏是有原因的。我过去曾遇到过一些有趣的问题。