【问题标题】:What do 1.#INF00, -1.#IND00 and -1.#IND mean?1.#INF00、-1.#IND00 和 -1.#IND 是什么意思?
【发布时间】:2010-09-25 18:20:00
【问题描述】:

我在处理一些使用浮点数的 C 代码,当我尝试在屏幕上打印浮点数时,我得到 1.#INF00、-1.#IND00 和 -1.#IND。这些值是什么意思?

我相信 1.#INF00 表示正无穷大,但是 -1.#IND00 和 -1.#IND 呢?我有时也看到这个值:1.$NaN 这不是一个数字,但是是什么导致了这些奇怪的值,这些值如何帮助我进行调试?

我正在使用MinGW,我相信它使用IEEE 754 表示浮点数。

谁能列出所有这些无效值以及它们的含义?

【问题讨论】:

  • 这是 Microsoft C 运行时库格式化 Infinity 和 NaN 浮点值的方式。 MinGW 没有自己的 CRT,它使用操作系统提供的 msvcrt.dll。它看起来的确切方式取决于您使用的 printf() 格式说明符,因此额外的零,它甚至可以turn into 1.#J。 C99 标准设置了预期的输出,在 VS2015 中采用,所以这个怪癖会消失。

标签: c++ c


【解决方案1】:

来自IEEE floating-point exceptions in C++

此页面将回答以下问题。

  • 我的程序刚刚打印出 1.#IND 或 1.#INF(在 Windows 上)或 nan 或 inf(在 Linux 上)。发生了什么?
  • 如何判断一个数字是否真的是一个数字,而不是 NaN 或无穷大?
  • 如何在运行时找到有关各种 NaN 和无穷大的更多详细信息?
  • 您有任何示例代码来说明其工作原理吗?
  • 在哪里可以了解更多信息?

这些问题与浮点异常有关。如果您在期望数字的地方得到一些奇怪的非数字输出,那么您要么超出了浮点运算的有限限制,要么您要求了一些未定义的结果。为简单起见,我将坚持使用双浮点类型。类似的说法也适用于浮点类型。

调试 1.#IND、1.#INF、nan 和 inf

如果您的操作生成的正数大于双精度数,则该操作将在 Windows 上返回 1.#INF,在 Linux 上返回 inf。同样,如果结果是负数太大而无法存储在双精度中,您的代码将返回 -1.#INF 或 -inf。正数除以零产生正无穷大,负数除以零产生负无穷大。本页末尾的示例代码将演示一些产生无穷大的操作。

某些运算没有数学意义,例如取负数的平方根。 (是的,这个操作在复数的上下文中是有意义的,但是双精度数表示一个实数,因此没有双精度数来表示结果。)对于负数的对数也是如此。 sqrt(-1.0) 和 log(-1.0) 都将返回 NaN,即“非数字”的“数字”的通用术语。 Windows 将 NaN 显示为 -1.#IND(“IND”表示“不确定”),而 Linux 显示 nan。其他会返回 NaN 的操作包括 0/0、0*∞ 和 ∞/∞。有关示例,请参见下面的示例代码。

简而言之,如果您得到 1.#INF 或 inf,请查找溢出或除以零。如果得到 1.#IND 或 nan,寻找非法操作。也许你只是有一个错误。如果它更微妙并且您有一些难以计算的东西,请参阅避免上溢、下溢和精度损失。那篇文章提供了计算结果的技巧,如果直接计算,则中间步骤会溢出。

【讨论】:

  • 我知道 OP 并没有真正要求这个,但作为一个方便的测试,如果你有这些神奇值之一,myfloat == myfloat 将返回 false。
  • @tenpn 实际上在 C++ 中,+infinity==+infinity。尝试检查 1.0 / 0.0:1.#INF00 == 1.#INF00 返回 true,-1.#INF00 == -1.#INF00 返回 true,但 1.#INF00 == -1.#INF00 为 false。
  • 不确定其他配置,但在 Windows 7 / Visual Studio 2010 上。 float nan = sqrtf(-1.0f);南==南; // 计算结果为真......与tenpn所说的相反......(Yevgen V评论)
  • 如果您可以使用 C++11,请查看 std::isfinite() 等。如果你可以使用 Boost,你就是 lucky as well
  • @Jeff 这可能与优化有关。见the relevant docs page
【解决方案2】:

对于任何想知道-1.#IND00-1.#IND 之间区别的人(该问题专门提出,并且没有答案地址):

-1.#IND00

这具体意味着一个非零数除以零,例如3.14 / 0 (source)

-1.#INDNaN 的同义词)

这意味着以下四件事之一(参见 source 中的 wiki):

1) sqrtlog 为负数

2) 两个变量都为 0 或无穷大的操作,例如0 / 0

3) 至少有一个变量已经是NaN 的操作,例如NaN * 5

4) 超出范围触发,例如arcsin(2)

【讨论】:

    【解决方案3】:

    您的问题“它们是什么”已经在上面得到解答。

    至于调试(您的第二个问题),以及在开发您想要检查特殊输入值的库时,您可能会发现以下函数在 Windows C++ 中很有用:

    _isnan()、_isfinite() 和 _fpclass()

    在 Linux/Unix 上,您应该会发现 isnan()、isfinite()、isnormal()、isinf()、fpclassify() 很有用(您可能需要使用编译器标志 -lm 与 libm 链接)。

    【讨论】:

      【解决方案4】:

      对于那些在 .NET 环境中的人来说,以下可能是一种过滤非数字的便捷方法(此示例在 VB.NET 中,但在 C# 中可能类似):

      If Double.IsNaN(MyVariableName) Then
          MyVariableName = 0 ' Or whatever you want to do here to "correct" the situation
      End If
      

      如果您尝试使用具有 NaN 值的变量,您将收到以下错误:

      对于 Decimal,值太大或太小。

      【讨论】:

      • 这不会检测到1.#INF。您还需要使用 Double.IsInfinity(MyVariableName) 来检查 +/- 无穷大。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多