C中的NaN文字?

Posted

技术标签:

【中文标题】C中的NaN文字?【英文标题】:NaN Literal in C? 【发布时间】:2011-08-08 12:27:56 【问题描述】:

如何在 C 中编写 NaN 浮点文字?

【问题讨论】:

@David:哦,真的吗?!这很奇怪。我正在使用 GCC,但知道 Visual C++ 的答案以后也会有所帮助。 其实我说错了。该标准确实谈到了 NaN,但它是可选的。 How to use nan and inf in C?的可能重复 复制Q有很多好东西 @David: 好吧...我搜索了一下,但一切都在 C++ 上;谢谢! 【参考方案1】:

在 C 中,您可以通过以下方式编写 NaN 浮点字面量。

const unsigned long dNAN[2] = 0x00000000, 0x7ff80000;
const double LITERAL_NAN = *( double* )dNAN;

请注意,这不是标准方式。在 Microsoft C 上,它运行良好。

【讨论】:

我喜欢你的风格,但总的来说,建议使用unions 而不是*(T*) 演员来做这样的鬼鬼祟祟的事情。执行 union uint64_t i; double d; nan = 0x7ff8000000000000; 然后使用 nan.d 作为 NaN 可能更便携。更好地使用 math.h 标头以获得可移植性。 使用联合确实有意义。我认为这是风格问题。常量 LITERAL_NAN 可以在没有成员访问运算符点的代码中使用。当涉及到定义样式时,您的建议更有意义。 @cmeeren 我没有在 x64 上尝试过,但它应该可以在 x64 上工作,因为 IEEE 754 双精度在 32 位和 64 位操作系统上始终是 64 位。 我想向那些可能不知道的人指出,这对于从两个 long 到 double 的字节对应与此答案中提出的不同的系统来说是不可移植的,即使根据 IEEE 标准,系统可能具有双精度。 (例如,在 long 为大端的架构上,但双精度与 x86 上的字节顺序相同。)您在回答中提到了 Microsoft C,它几乎定义了目标架构(英特尔 x86 或 x86_64),但关于便携性很容易被忽略。 这违反了严格的别名规则,并且通常具有 UB。也就是说,这可能不适用于某些版本的 GCC。【参考方案2】:

使用NAN 更好,但如果您在一个具有 NaN 的系统上,0.0/0.0 是一个简单的方法...

【讨论】:

【参考方案3】:

5.2.4.2.2/3:

浮动类型可以包含 其他类型的浮点数, 例如...无穷大和NaN。 NaN 是一种编码 表示非数字。一个安静的 NaN 传播几乎 每个算术运算都没有 引发浮点异常;一种 信号 NaN 通常会引发 发生浮点异常时 作为算术操作数。

7.12/5 (math.h):

NAN 被定义当且仅当 该实现支持安静的 NaN 对于浮点类型。它扩展为 float 类型的常量表达式 代表安静的 NaN。

所以你可以得到一个值 if 你的实现完全支持 NaN,并且 if 这些 NaN 中的一些或全部是安静的。未能进入实现定义的领域。

其中一些浮点宏也有点担心,编译器前端可能不知道它是否支持该功能,因为它生成的代码可以在多个版本上运行支持变化的架构。我不知道这是否适用于这个宏,但这是您进入实现定义领域的另一种情况 - 预处理器可能保守地声称它不支持该功能,而实际上是整个实现,就像您一样正在使用它,确实如此。

【讨论】:

【参考方案4】:

在C99的<math.h>

  7.12  Mathematics <math.h>
   [#5] The macro

           NAN

   is defined if and only if the implementation supports  quiet
   NaNs   for  the  float  type.   It  expands  to  a  constant
   expression of type float representing a quiet NaN.           |

【讨论】:

以上是关于C中的NaN文字?的主要内容,如果未能解决你的问题,请参考以下文章

[记] C语言中的nan和inf

如果前五列中的 NaN 则删除行

将列表中的 NaN 值替换为零 (0)

如何合并/组合熊猫中的列?

在C中识别和分配+ NaN和-NaN

函数中的 NaN