在 C++ 中使用 NaN?
在 C++ 中使用 NaN 的最佳方法是什么?
我找到了 std::numeric_limits
和 std::numeric_limits
。 我想使用 signaling_NaN 来表示未初始化的变量,如下所示:
double diameter = std::numeric_limits<double>::signaling_NaN();
但是,这会在赋值时发出信号(引发异常)。 我希望它在使用时引发异常,而不是在分配时引发异常。
有没有办法使用signaling_NaN而不引发赋值异常? 是否有一个好的、可移植的信号替代方案来替代signaling_NaN,在使用时会引发浮点异常?
What's the best way to use NaNs in C++?
I found std::numeric_limits<double>::quiet_NaN()
and std::numeric_limits<double>::signaling_NaN()
. I'd like to use signaling_NaN
to represent an uninitialized variable as follows:
double diameter = std::numeric_limits<double>::signaling_NaN();
This, however, signals (raises an exception) on assignment. I want it to raise an exception on use, not on assignment.
Is there any way to use signaling_NaN
without raising an exception on assignment? Is there a good, portable alternative to signaling_NaN
that will raise a floating point exception when used?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
经过更多研究后,看起来
signaling_NaN
所提供的毫无用处。 如果启用了浮点异常,则调用它会被视为处理信号 NaN,因此它会立即引发异常。 如果禁用浮点异常,则处理信号 NaN 会自动将其降级为安静 NaN,因此signaling_NaN
无论如何都不起作用。Menkboy 的代码 可以工作,但尝试使用信号 NaN 会遇到其他问题:没有可移植的启用或禁用浮点异常的方法(如此处提到的 和此处),如果您依赖启用的异常,第三方代码可能会禁用它们(如此处所述)。
所以看起来 Motti 的解决方案确实是最好的选择。
After looking into this some more, it looks like
signaling_NaN
is useless as provided. If floating point exceptions are enabled, then calling it counts as processing a signaling NaN, so it immediately raises an exception. If floating point exceptions are disabled, then processing a signaling NaN automatically demotes it to a quiet NaN, sosignaling_NaN
doesn't work either way.Menkboy's code works, but trying to use signaling NaNs runs into other problems: there's no portable way to enable or disable floating point exceptions (as alluded to here and here), and if you're relying on exceptions being enabled, third party code may disable them (as described here).
So it seems like Motti's solution is really the best choice.
发信号 NAN 的意思是,当 CPU 遇到它时,会发出一个信号(因此得名)。 如果您想检测未初始化的变量,那么提高编译器的警告级别通常会检测到所有使用未初始化值的路径。 如果失败,您可以使用一个包装类来存储一个布尔值,表示该值是否已初始化:
What signaling NAN means is that when the CPU encounters it a signal is fired, (hence the name). If you want to detect uninitialized variables then raising the warning level on your compiler usually detects all paths that use uninitalized values. Failing that you can use a wrapper class that stores a boolean saying if the value is initialized:
您可以将信号 NaN 写入变量,而不会触发异常,如下所示(注意:未经测试)
它可以在大多数地方工作,但不,它不是 100% 可移植的。
You can write a signalling NaN into a variable without triggering an exception with something like this (nb: untested)
It'll work most places, but no, it's not 100% portable.
好吧,看看安静和信号 NaN 的定义,我真的看不出有什么区别。
您可以自己使用这些函数中使用的代码,也许这样可以防止异常,但是在这两个函数中没有看到异常,我认为它可能与其他东西有关。
如果你想直接赋值 NaN:
Well, looking after the definition of both quiet and signaling NaN, I can't really make out any difference.
You could use the code that is used in those functions yourself, maybe it prevents an exception that way, but seeing no exception in those two functions, I think it might be related to something else.
If you want to directly assign the NaN:
简单回答:
在头文件中执行类似的操作并在其他地方使用它:
如果您希望对它们进行某种操作,最好在
exp()
周围编写一些扩展包装函数,例如extended_exp()< /代码>等等!
Simple answer:
Do something like this in the header file and use it everywhere else:
If you wish to do some kind of manipulations on them better write some extended wrapper function around
exp()
likeextended_exp()
and so on!您的 C++ 实现可能具有用于访问浮点环境的 API,以测试和清除某些浮点异常。 有关详细信息,请参阅我对相关问题的回答。
Your C++ implementation may have an API for accessing the floating point environment to test for and clear certain floating point exceptions. See my answer to a related question for more information.