【问题标题】:C++ Why convert something to NaN? [closed]C++ 为什么要将某些东西转换为 NaN? [关闭]
【发布时间】:2017-02-16 19:25:26
【问题描述】:

我的理解是,NaN(非数字)本质上是一个从数学函数返回的常数,表示出现问题或计算无效。因此,它们是检查数字是否为 NaN 或更好的函数是有道理的,使用 CERT 编码标准对数学错误进行错误检查 (https://www.securecoding.cert.org/confluence/display/c/FLP32-C.+Prevent+or+detect+domain+and+range+errors+in+math+functions)。

我的问题是这样的;为什么 std::nan() 存在?为什么你会想要一个有效的数字/字符串/值并将其转换为 NaN? (参考:http://en.cppreference.com/w/cpp/numeric/math/nan

【问题讨论】:

  • 与标准的完整性。 NaN 可以有不同的值。可能有必要为测试代码创建一个特定的 NaN,以进行比较。甚至可能需要在运行时检测特定的 NaN。
  • 这是否意味着存在一系列代表特定错误的 NaN 常量?
  • 可以在库中使用的 NaN!嘘!
  • @Katianie 一个信号 NAN 可能会导致 CPU 异常(一个安静的不是)
  • 没有对应于不同NaN 值的特定错误。来自the spec“库实现可以使用该参数以特定于实现的方式区分不同的 NaN 值。” 请注意,甚至不需要实现支持不同的NaN 值。 (quiet NaN 是一个 NaN,如果它在操作中使用并简单地传播,则不会引发异常。有关更多信息,请参阅 WIkipedia article on NaN。)

标签: c++ math nan


【解决方案1】:

假设你想实现 std::acos。如果输入无效(|arg|

【讨论】:

  • 这就是我实现 acos 的方式: if (islessequal(-1, numInRadians) == true && islessequal(numInRadians, 1) == true) { return acos(numInRadians); } 返回 -1.0;
  • @Katianie 假设您没有要调用的 acos 函数。
  • 好点,如果我没有 acos 可以打电话。但是由于我在这种情况下这样做,对于我的其他数学函数,我会以与 CERT 标准相同的方式检查轮询和域错误(请参阅我的问题中的链接)。这样我就不会真正接触到 NaN 值。
  • @Katianie,检查您没有调用具有域外值的数学函数的一种方法是提前检查,每次调用函数时 ,正如您所建议的那样,知道该 fn 的域。另一种方法(在 IEEE 算术中)只是调用该函数并查看它是否返回一个 NaN。后者的优势在于,如果您使用传播的安静 NaN,您可以计算整个表达式,并最终确定在该计算期间的任何时间您是否超出域。 (或者,如果您使用信号 NaN,您将在域外时抛出异常。)
【解决方案2】:

NaN 通常用于表示空值或缺失值,尤其是在数据分析和数据科学中。因此,应用程序通常会将值初始化为 nan,以便跟踪是否已提供值,而无需使用类似 optional<T> 的结构的开销。

其次,创建自定义数学函数是很常见的,您希望为某些输入返回 nan。所以这不仅仅是为了完整性。

【讨论】:

  • 那么您可以使用 NaN 进行带内错误信令吗?出于好奇,您有任何示例库,我可以查看它的文档吗?
  • Numpy 和 pandas 就是一个很好的例子:pandas.pydata.org/pandas-docs/stable/missing_data.html
  • 接下来,这里首选 nans 的原因是您可以像往常一样继续使用 nans 进行计算(例如在大向量运算中),并且 nan 值自然会传播到最终结果,并且仅受到影响的价值观。
【解决方案3】:

IEEE 754 系统地引入了使用 NaN 来表示数字,否则这些数字的定义无法在计算机上表示。

您会经常看到 0/0、±inf / ±inf、0 * ±inf 等。

【讨论】:

  • 但是是否为那些域外结果定义了(在标准中)不同的 NaN?
  • 查看此链接:securecoding.cert.org/confluence/display/c/… 我关注了如何检查轮询和域错误。
  • @davidbak 按照标准,我假设您的意思是 IEEE 标准。在 754 中,有一些关于 NaN 的有趣含义。具体来说,对 NaN 定义为真的唯一操作是 NaN != NaN,因此没有两个 NaN 是相同的。
猜你喜欢
  • 2023-03-04
  • 1970-01-01
  • 2013-01-11
  • 1970-01-01
  • 1970-01-01
  • 2017-07-12
  • 2016-07-22
  • 1970-01-01
  • 2013-01-26
相关资源
最近更新 更多