浮点 - 在C++中使用 NaN
floating point - Using NaN in C++?
在C++中使用NaN的最佳方法是什么?
我找到了std::numeric_limits<double>::quiet_NaN()
和std::numeric_limits<double>::signaling_NaN()
. 我想用signaling_NaN
来表示一个未初始化的变量,如下所示:
double diameter = std::numeric_limits<double>::signaling_NaN();
但是,这在分配时发出信号(引发异常)。 我希望它在使用时而不是分配时引发异常。
有没有办法在不引发分配异常的情况下使用 signaling_NaN
? 是否有一种好的、可移植的替代方案来替代signaling_NaN
,在使用时会引发浮点异常?
在进一步研究之后,看起来signaling_NaN
是无用的。 如果启用了浮点异常,则调用它计为处理信令 NaN,因此它会立即引发异常。 如果禁用浮点异常,则处理信令 NaN 会自动将其降级为安静 NaN,因此signaling_NaN
无论哪种方式都不起作用。
Menkboy 的代码可以工作,但尝试使用信令 NaN 会遇到其他问题:没有可移植的方法来启用或禁用浮点异常(如此处和此处所述),如果您依赖于启用异常,第三方代码可能会禁用它们(如此处所述)。
因此,看起来Motti的解决方案确实是最佳选择。
信令 NAN 的意思是,当 CPU 遇到它时,会触发信号(因此得名)。如果要检测未初始化的变量,则提高编译器上的警告级别通常会检测使用未初始化值的所有路径。如果做不到这一点,您可以使用一个包装类来存储一个布尔值,如果值被初始化:
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;
}
};
您可以将信令 NaN 写入变量,而不会触发异常(注意:未经测试)
void set_snan( double &d )
{
long long *bits = (long long *)&d;
*bits = 0x7ff0000080000001LL;
}
它可以在大多数地方工作,但不,它不是 100% 便携的。
好吧,考虑到安静和信号 NaN 的定义,我真的无法区分任何区别。
您可以自己使用这些函数中使用的代码,也许它可以防止异常,但是在这两个函数中没有看到异常,我认为它可能与其他内容有关。
如果要直接分配 NaN:
double value = _Nan._Double;
简单的答案:在头文件中执行类似操作,并在其他任何地方使用它:
#define NegativeNaN log(-1)
如果你想对它们进行某种操作,最好围绕exp()
编写一些扩展的包装器函数,比如extended_exp()
等等!
您的C++实现可能具有用于访问浮点环境的 API,以测试和清除某些浮点异常。 有关更多信息,请参阅我对相关问题的回答。
- g++的分段错误(在NaN上使用to_string两次时)
- 输出是NaN,如何
- 为什么我在输出端得到 nan?
- 提升反序列化对象具有 nan 或 -nan 值
- Is !NaN not a NaN?
- NaN 上的宇宙飞船操作员
- C++ STL 排序会检查 NaN 吗?
- C++ 每次运行程序时我都会"nan"输出的问题
- 复制 -nan 表示浮点数,AVX __m256 复制后显示 0
- 如何使用 Node-addon-API 实现 node-nan 回调
- 为什么我的双变量通过添加 c++ 显示 nan?
- nan() 函数的参数
- 为什么 acos() 在使用点积的结果时会导致"nan(ind)"?
- 如何在 c++ 中处理 -nan 输出
- 为什么这段代码返回 -nan(ind)?C++
- Pybind11+nan节点模块冲突
- Nan::ObjectWrap to Napi::Object Wrap 无法访问 JavaScript 中的属性
- 第二个 while 循环未运行,将值设置为 "nan"
- 无穷大与 NAN 值
- 调用某个回调函数两次会导致分段错误:Nan