浮点数 Inf 和 NaN 的来源
内容提要
在安全编程中,及时发现浮点Inf和NaN值的生成非常重要,尤其是当这些值只在计算过程中出现并在输出中丢失时。在浮点计算中,NaN值会通过计算传播,而Inf值会通过计算传播或变为NaN。因此,我们需要了解浮点计算中Inf和NaN值的来源。本文展示了浮点计算中一些Inf和NaN值的来源,并给出了相应的代码和结果。
延伸解读
检查时机的选择
文章指出,在浮点计算中,NaN会传播,Inf会传播或变为NaN。因此,如果计算完全在浮点域内,可以跳过中间检查,直到可能丢失这些值的操作或最终输出。但如果涉及转换为无Inf/NaN表示的类型(如整数),则需要在转换前检查。此外,如果已知前置计算不会产生Inf/NaN,可以消除检查。这有助于在安全编程中平衡性能与正确性。
常见生成来源示例
文章通过代码示例展示了多种Inf和NaN的来源:直接使用NAN宏、除以零(1.0f/0.0f得Inf,0.0f/0.0f得NaN)、数学函数如sqrt(-1)和log(-1)返回NaN、以及溢出操作如float最大值乘2得Inf。这些示例帮助读者识别实际计算中可能出现的异常值。
Inf与NaN的运算规则
从示例结果可总结出一些规则:Inf减Inf得NaN,Inf加Inf得Inf,Inf乘0得NaN,Inf除以0得Inf,Inf乘或除以非零有限值得Inf。这些规则有助于预测计算中异常值的传播,从而在必要时添加检查。
整数转换的潜在风险
文章提到,将浮点值转换为整数等无Inf/NaN表示的类型可能导致值丢失。示例中,两个int32最大值转换为float后相乘得到有限值4.61169e+18,未产生Inf/NaN,但若结果超出整数范围,转换将导致未定义行为。因此,在转换前检查浮点值是否为Inf/NaN或超出目标类型范围是必要的。
Q&A
浮点数中的Inf和NaN值是什么?
Inf表示无穷大,NaN表示不是一个数字,它们在浮点计算中可能会出现。
为什么在安全编程中需要关注Inf和NaN值?
因为这些值可能在计算过程中生成并导致输出丢失,影响程序的安全性和准确性。
如何检测浮点计算中的Inf和NaN值?
可以通过编写代码检查计算结果,使用如std::isnan和std::isinf等函数进行检测。
在什么情况下需要检查浮点数的Inf和NaN值?
在进行可能导致值丢失的操作之前,尤其是转换为不支持Inf和NaN的其他数据类型时。
浮点计算中Inf和NaN值的生成有哪些常见来源?
常见来源包括除以零、无效的数学操作(如平方根负数)和超出数据类型范围的计算。
如何通过代码示例实验Inf和NaN值的生成?
可以使用提供的代码示例,调用check_inf_nan_value函数来测试不同的浮点计算。