【问题标题】:Sign check for NaN valueNaN 值的符号检查
【发布时间】:2012-02-05 13:17:55
【问题描述】:

我的程序在计算过程中可以生成nan-nan 值。 我使用isnan 方法检查值是否为nan/-nan

我还必须区分 nan 值是正数还是负数(nan-nan)。我该怎么做?

补充:我需要 WIN 和 Unix/Linux 的跨平台解决方案

【问题讨论】:

  • 如果它不是一个数字......确定“它的”符号是否有意义? ??????
  • @pmg - nan 和 -nan 之间存在差异
  • @Yakov 请告诉我们区别。什么算术运算赋予它返回的 NaN 值的符号含义?
  • @David Heffernan: catan(inf + iNAN) => π/2 + i0; catan(inf - iNAN) => π/2 - i0;

标签: c visual-studio unix nan sign


【解决方案1】:

当今几乎所有系统都使用 IEEE 单精度或双精度浮点。因此,在这种情况下,您可以(按位)将其转换为整数并读取符号位。

这是一种使用联合的方法。虽然它不完全符合标准,但它仍然可以在几乎所有系统上运行。

union{
    double f;
    uint64_t i;
} x;

x.f = ... //  Your floating-point value (can be NaN)

//  Check the sign bit.
if ((x.i & 0x8000000000000000ull) == 0){
    //  positive
}else{
    //  negative
}

【讨论】:

    【解决方案2】:

    <math.h> 尝试signbit

    说明

    signbit() 是一个通用宏,可以处理所有真正的浮点数 类型。如果 x 的值有符号位,则返回非零值 设置。

    ...

    NaN 和无穷大都有符号位。

    它显然是 C99 和 POSIX.1-2001 的一部分,但如果您不想使用/遵守两者中的任何一个,您可以自己编写宏/函数。

    【讨论】:

    • 跨平台系统需要它。如何使它适用于 Visual Studio?
    • @Yakov:抱歉回复晚了。 Microsoft 可能有自己的类似于signbit 的宏/功能,或者您可以查找signbit 实现的源代码。一个示例是 here 与关联的标头 here
    【解决方案3】:

    您可以使用copysign 函数(C99,在<math.h>);

    double sign = copysign(1.0, your_nan);
    

    来自 C99 §7.12.11.1:

    说明

    copysign 函数产生一个大小为 x 且符号为 y 的值。 如果 x 是 NaN,它们会产生 NaN(符号为 y)。关于实现 表示有符号的零,但在算术中不始终如一地对待负零 操作中,copysign 函数将零的符号视为正数。

    返回

    copysign 函数返回一个带有 x 大小和 y 符号的值。

    【讨论】:

      猜你喜欢
      • 2012-02-07
      • 2010-10-30
      • 2015-03-26
      • 1970-01-01
      相关资源
      最近更新 更多