1.#INF00,-1。#IND00和-1。#IND是什么意思?


67

我在弄乱一些使用浮点数的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()格式说明符,因此多余的零甚至可以变成1.#J。C99标准设置了VS2015中采用的预期输出,因此这个怪癖将消失。
汉斯·帕桑

Answers:


70

C ++中的IEEE浮点异常开始

该页面将回答以下问题。

  • 我的程序刚刚打印出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,请查找非法操作。也许您只是有一个错误。如果它更微妙,并且您有一些难以计算的内容,请参阅避免溢出,下溢和精度损失。该文章提供了一些计算结果的技巧,如果直接计算,中间步骤会溢出。


4
我知道OP并没有真正要求这样做,但是作为一种方便的测试,myfloat == myfloat如果您具有以下这些魔术值之一,它将返回false。
tenpn 2012年

8
@tenpn实际上在C ++中,+ infinity == + infinity。尝试检查1.0 / 0.0:1.#INF00==1.#INF00返回true,-1.#INF00==-1.#INF00返回true,但是1.#INF00==-1.#INF00为false。
bobobobo '02

2
不确定其他配置,但在Windows 7 / Visual Studio 2010上不确定。float nan = sqrtf(-1.0f); nan == nan; //评估为true ...与tenpn所说的相反。.(评论由耶夫根五世)
Jeff

如果可以使用C ++ 11,请查看std :: isfinite()等。如果你可以使用升压你幸运以及
马特乌斯·布兰德

2
@Jeff可能与优化有关。请参阅相关的文档页面
罗斯兰

6

对于任何想知道-1.#IND00和之间的区别的人-1.#IND(问题专门提出了这个问题,答案都没有解决):

-1.#IND00

具体来说,这意味着非零数字除以零,例如3.14 / 0source

-1.#IND(的同义词NaN

这意味着四件事之一(请参阅来自源的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链接)。


3

对于.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值的变量,则会出现以下错误:

对于小数,值太大或太小。


4
这不会检测到1.#INF。您还需要使用Double.IsInfinity(MyVariableName)来检查+/-无限大。
user1318499 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.