我有双(或浮点)变量可能是“空”,就像没有有效值一样。如何用内置类型float和double来表示这个条件?
一个选项是一个包含浮点数和布尔值的包装器,但这不起作用,因为我的库有容器存储双精度而不是表现为双精度的对象。另一个是使用NaN(std :: numeric_limits)。但我认为无法检查变量是否为NaN。
如何解决需要“特殊”浮点值来表示数字以外的其他问题?
答案 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)宏是有原因的。我过去曾遇到过一些有趣的问题。