如何判断浮点数是 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的主要内容,如果未能解决你的问题,请参考以下文章