揭秘 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值,确保软件可以优雅地处理边缘情况,并在整个计算过程中保持数值的完整性。
热门推荐
企业高层如何判断项目投资回报率?5个关键评估方法!
观点 | ESG视角下纺织业可持续发展的挑战与机遇浅析
海外公司注册资金全景解析:选择全球注册地的资金要求和最佳实践
从《资治通鉴》中汲取人生智慧:八大启示助你走向成功
i3 3240怎么发挥全部性能?提升你处理器性能的终极指南!
Pro加密锁的应用领域有哪些
数字囤积需要断舍离吗?
白内障手术收费标准一览表:超声乳化/飞秒激光/晶体植入技术价格表均有!
机械硬盘寿命一般多久?寿命到期有哪些表现?
矢量图是什么意思
矢量图格式有几种?5大主流格式一网打尽
防火墙的工作原理与局限性
基于FPGA的低成本、低延时成像系统设计方案
Aspen数据库不全怎么办?完整解决方案来了
揭开重复内容对SEO的影响:如何遵循Google标准提升网站价值
春季干咳怎么办?5类药物对症治疗,快速缓解不适!
观音诞是怎么来的?观音诞时有哪些习俗?
揭开成语故事的秘密:从古代典故到现代应用,带你领悟成语背后的深刻寓意!
费用结构是什么?如何有效管理费用结构?
麒麟瓜:一种改良的西瓜品种
业内人士热议半导体产业复苏新动能:功率半导体与AI应用
主动辞职和被辞退的区别
什么是CMA认证和CNAS认证?与CQC、3C、CE有什么不同?
情绪价值在职场人际关系中起到的重要作用
根本原因分析:5 个为什么方法
补语和状语的区别_高中语文知识点解答
中听丨应对老年违法犯罪, 不是调整处罚年龄这么简单
多路复用技术是什么?有哪些类型
项目没中标如何解决管理人员
树莓种子的种植方法(从选种到管理)