浮点数 Inf 和 NaN 的来源

💡 原文英文,约900词,阅读约需4分钟。
📝

内容提要

在安全编程中,及时发现浮点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函数来测试不同的浮点计算。

➡️

继续阅读