如何判断浮点数是 SNAN 还是 QNAN

Posted

技术标签:

【中文标题】如何判断浮点数是 SNAN 还是 QNAN【英文标题】:How to tell if a float is SNAN or QNAN 【发布时间】:2015-04-16 05:44:07 【问题描述】:

我试图弄清楚如何打印出浮点数是 QNAN 还是 SNAN。我已经将这些位分成了 signBit exponentBit 和 FractBits。

unsigned int sign = (i & 0x80000000) >> 31;
unsigned int exponent = (i & 0x7f800000) >> 23;
unsigned int fraction = (i & 0x007FFFFF);
printf("signBit %d, expBits %d, fractBits 0x%08X\n",sign, exponent, fraction);

【问题讨论】:

您可以从common mathematical functions in the standard library 获得一些 帮助,您还可以使用std::numeric_limits 确定一个类型是否具有不同的NaN 类型。 IEEE 754 没有定义特定 NaN 的二进制格式。信令 NaN 的存在和格式取决于平台(通常是硬件和操作系统)。 【参考方案1】:

GNU provides 是 recently standardized 的设施:

宏:int issignaling (float-type x)

初步:| MT-安全 | AS-安全 |交流安全 |请参阅 POSIX 安全概念。

如果 x 是信号 NaN (sNaN),则此宏返回非零值。它基于草案 TS 18661,目前作为 GNU 启用 扩展名。

最终草案 TS 提到您可能需要选择加入宏才能获得它:

#define __STDC_WANT_IEC_60559_BFP_EXT__
#include <math.h> 
int issignaling(real-floating x);

【讨论】:

一些平台有fpclass()/_fpclass(),它类似于fpclassify(),除了它区分安静和信号NaN。 @cremno 不过,这似乎不是 ISO 采用的路线。 TS 只承认它将“提供 IEC 60559 附录中推荐的类功能的设施(除了 7.12.3 中定义的分类宏不区分信号和安静的 NaN)。” (IEC 60559 是 IEEE 754 的继任者。) 是的,我只是想提一下,因为不是每个人都在使用 glibc,而且似乎还没有另一个(开源/公共)实现。 @Potatoswatter:其实IEC 60559,诞生于IEC 559,标准与IEEE 754相同,只是由另一个标准机构发布,不同的cover letter,但其他内容相同; ISO 委员会 WG14 使用 IEC 参考只是因为 ISO 政治; IEC 60559:2011 与 IEEE 754:2008 相同,它们是 IEC 559:1989 / IEEE 754:1985 的实质性修订(后续)。这里重要的是修订。 @AntoineL github.com/cplusplus/draft/issues/343 。唯一比这种橡皮图章政治化更令人难以置信的是,我们让自己不便研究并发现它们真的毫无意义。【参考方案2】:

浮点实数的格式取决于处理器。在 x86 / x86-64 ISA 上,有效数的最高位 = 1 表示安静,0 表示信号。 (NaN 有效载荷的其余部分仍然是任意的)。

float 类型:

double 类型:

long double 类型(微软编译器不支持):

【讨论】:

以上是关于如何判断浮点数是 SNAN 还是 QNAN的主要内容,如果未能解决你的问题,请参考以下文章

JS判断是不是为数字,是不是为整数,是不是为浮点数

js中如何判断两个浮点数是不是相等

如何检查字符串是浮点数还是整数?

如何在shell中对浮点数进行计算

golang比较浮点数是不是相等

如何检查数字是浮点数还是整数?