首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C++中使用NaN?

在C++中使用NaN?
EN

Stack Overflow用户
提问于 2008-10-24 21:56:23
回答 6查看 33.8K关注 0票数 33

在C++中使用NaNs的最佳方式是什么?

我找到std::numeric_limits<double>::quiet_NaN()std::numeric_limits<double>::signaling_NaN()了。我想使用signaling_NaN来表示一个未初始化的变量,如下所示:

代码语言:javascript
复制
double diameter = std::numeric_limits<double>::signaling_NaN();

然而,这会在赋值时发出信号(引发异常)。我希望它在使用时引发异常,而不是在赋值时。

有没有办法在不引发赋值异常的情况下使用signaling_NaN?有没有一个很好的、可移植的signaling_NaN替代方案,可以在使用时引发浮点异常?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2008-11-11 18:32:36

经过更多的研究,signaling_NaN看起来就像所提供的那样没有用。如果启用了浮点异常,则调用它将被视为处理信号NaN,因此它会立即引发异常。如果禁用了浮点异常,则处理信令NaN会自动将其降级为静默NaN,因此signaling_NaN在这两种方式中都不起作用。

Menkboy's code可以工作,但尝试使用信令NaNs会遇到其他问题:没有可移植的方法来启用或禁用浮点异常(如herehere所暗示的),如果您依赖于启用异常,则第三方代码可能会禁用它们(如here所述)。

所以看起来Motti's solution确实是最好的选择。

票数 11
EN

Stack Overflow用户

发布于 2008-10-25 20:02:28

发信号NAN的意思是,当CPU遇到NAN时,就会触发一个信号(由此得名)。如果您想要检测未初始化的变量,那么提高编译器上的警告级别通常会检测到所有使用未初始化的值的路径。如果不是这样,您可以使用一个包装类来存储一个布尔值,该布尔值表示该值是否已初始化:

代码语言:javascript
复制
template <class T>
class initialized {
    T t;
    bool is_initialized;
public:
    initialized() : t(T()), is_initialized(false) { }
    initialized(const T& tt) : t(tt), is_initialized(true) { }
    T& operator=(const T& tt) { t = tt; is_initialized = true; return t; }
    operator T&() {
         if (!is_initialized)
             throw std::exception("uninitialized");
         return t; 
   }
};
票数 9
EN

Stack Overflow用户

发布于 2008-10-24 22:36:00

您可以将信令NaN写入变量,而不会触发异常,如下所示(nb:未测试)

代码语言:javascript
复制
void set_snan( double &d )
{
    long long *bits = (long long *)&d;
    *bits = 0x7ff0000080000001LL;
}

它可以在大多数地方使用,但不是100%便携的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/235386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档