问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

揭秘 C++ 中的 NaN:产生原因、特性详解及处理方法

创作时间:
作者:
@小白创作中心

揭秘 C++ 中的 NaN:产生原因、特性详解及处理方法

引用
CSDN
1.
https://blog.csdn.net/csdnnews/article/details/137580018

NaN(Not a Number)是C++中一个特殊的浮点数值,用于表示无法定义或不确定的数值结果。在编程中,特别是在进行数学计算时,了解NaN的产生原因、特性以及如何处理它,对于确保程序的正确性和稳定性至关重要。本文将深入探讨NaN的相关知识,帮助开发者更好地理解和应对这一特殊数值。

一、NaN 是如何产生的?

NaN值通常由那些无法产生确定或实数结果的操作产生,常见的场景包括:

  • 零除以零
  • 无穷大除以无穷大
  • 零乘以无穷大
  • 带相反符号的无穷级数相加
  • 计算负数的平方根
  • 取负数的对数
  • 使用非数字操作数进行复杂的数学运算

在C++中,还可以通过以下方式显式创建NaN值:

double nanValue = std::nan("0");
double quietNan = std::numeric_limits<double>::quiet_NaN();

二、NaN 的特性

NaN的一个显著特点是其在比较时的行为。在全等运算中,NaN与其他任何值(包括它自己)相比,结果都是false。示例如下:

double nanValue = 0.0 / 0.0;
bool alwaysFalse = nanValue == nanValue; // false
bool alwaysTrue = nanValue != nanValue; // true

要判断一个值是否为NaN,可以使用以下方法:

bool isNan = nanValue != nanValue;

C++标准库从C++11开始提供了内置函数std::is_nan来检查一个数字是否为NaN。

三、NaN 对数据结构的影响

在使用关联容器(如std::set)时,NaN会导致一些特殊问题。由于NaN不满足关联容器键的严格弱排序要求,一旦容器中包含NaN值,将无法再插入其他值。例如:

std::set<double> test;
test.insert(nanValue);
test.insert(1.0); // 不会插入
test.insert(2.0); // 不会插入

四、NaN 的标准和类型

根据IEEE 754标准,NaN值分为两种类型:

  • Quiet NaNs(qNaNs):允许计算继续进行而不受干扰,在算术运算中悄无声息地传播。
  • Signaling NaNs(sNaNs):会触发异常,立即处理无效操作。

虽然这两种NaN类型的区别很重要,但在C++或IEEE 754标准库接口中并没有明确处理,更多地取决于底层硬件和编译器行为。

五、检查 NaN

各种数学库都提供了NaN检查函数。例如,glm库可以检查向量的各个分量是否为NaN,并返回一个布尔向量:

glm::dvec3 nanVector = someFunction();
bool isNaN = glm::all(glm::isnan(nanVector));

更推荐的做法是检查数字是否有限,这可以通过std::isfinite函数实现:

std::println("{}", std::isfinite(std::numeric_limits<double>::quiet_NaN()));
std::println("{}", std::isfinite(std::numeric_limits<double>::infinity()));
std::println("{}", std::isfinite(-std::numeric_limits<double>::infinity()));
std::println("{}", std::isfinite(0.0));
std::println("{}", std::isfinite(std::exp(1000)));
std::println("{}", std::isfinite(std::numeric_limits<double>::min()));

六、结论

在C++中处理NaN值需要了解它们的生成、属性以及对数据结构的影响。通过利用内置函数并遵循最佳实践,开发人员可以有效管理NaN值,确保软件可以优雅地处理边缘情况,并在整个计算过程中保持数值的完整性。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号