5

我有可能是“空”的双(或浮点)变量,因为没有有效值。如何使用内置类型 float 和 double 来表示这种情况?

一种选择是具有浮点数和布尔值的包装器,但这不起作用,因为我的库有存储双精度数的容器,而不是表现为双精度数的对象。另一个将使用 NaN (std::numeric_limits)。但我看不出有什么方法可以检查变量是否为 NaN。

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

4

4 回答 4

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为此调用的宏 in math.h,它也检查浮点数是否为 NaN 值。

于 2008-12-02T00:50:55.253 回答
6

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

在 C 中,有一个isnan(double)函数可以通过math.h.

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

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

于 2008-12-02T00:59:11.697 回答
2

它不是内置类型,但我通常boost::optional用于这种事情。如果你绝对不能使用它,也许指针可以解决问题——如果指针为 NULL,那么你就知道结果不包含有效值。

于 2008-12-02T01:04:52.027 回答
1

一种选择是具有浮点数和布尔值的包装器,但这是行不通的,因为我的库有存储双精度数的容器,而不是表现为双精度数的对象。

真可惜。在 C++ 中,创建一个自动转换为实际双(引用)属性的模板类是微不足道的。(或对任何其他类型的引用。)您只需在模板类中使用强制转换运算符。例如:operator TYPE & () { 返回值;然后,您可以在通常使用双精度的任何地方使用 HasValue<double>。

另一个将使用 NaN (std::numeric_limits)。但我看不出有什么方法可以检查变量是否为 NaN。

正如litbJames Schek所说,C99 为我们提供了 isnan()。

但要小心!Nan值使数学和逻辑变得真正有趣!你会认为一个数字不能同时是 NOT>=foo 和 NOT<=foo。但是对于 NaN,它可以。

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

于 2008-12-02T06:36:04.217 回答