我在LINUX RHEL 64bit中编写代码,并使用C ++ 98。
我有一个浮点值数组,我想'标记'某些值为'无效'。一种可能的解决方案是使用另一个位数组来判断相应的值是否有效。
我想知道我们是否可以使用任何特殊的双倍值。链接Why does IEEE 754 reserve so many NaN values?表示有很多NaN值。我们可以使用为我的问题保留的任何值吗?
答案 0 :(得分:3)
一般来说,IEEE-754允许但不要求支持NaN有效载荷。但是,这里我们有x64系统的具体情况,AMD和Intel的相关处理器支持NaN有效负载。
IEEE标准754-2008进一步规定,对于NaN编码,尾数的最重要部分比特区分安静和信令NaN。这对应于单精度和双精度类型的最重要的存储的尾数位。因此,不能将此位用于自定义编码目的。 x64处理器生成特定的QNaN INDEFINITE以响应各种异常情况,并且QNaN编码的符号位用于此,因此符号位也禁止自定义基于NaN的标记。各种工具链提供宽松的,符合IEEE-754标准的“快速数学”,其中不保证NaN的传播。您需要使用最严格的浮点设置(例如英特尔编译器-fp-model strict
)进行编译,以确保自定义标记不会丢失。各种软件环境使用NaN有效负载来编码导致NaN创建的特定事件(Apple的SANE是此类系统的历史示例)。根据我的经验,这种系统通常利用NaN编码的尾数部分的低阶位。
这表明高阶尾数位,比如IEEE-754双精度数的50:48位或IEEE-754单精度数的21:19位是放置自定义标志的最佳位置在NaN编码内部(保留未触及的最重要的尾数位,如上所述)。通过float
和double
类型传输数据可能会有问题,因为x64架构规范未指定在不同浮点类型之间传播NaN有效负载,我可以从审查AMD的原始x64架构中找到最佳规范和英特尔最新文档。纯粹凭经验,我发现处理NaN有效负载使得单精度编码的bit [n]显示为双精度编码的bit [n + 29],反之亦然。
考虑到编程语言的限制,最好使用memcpy()
在浮点和无符号整数表示之间进行传输,并执行所需的位级操作来设置,清除,测试自定义NaN有效负载。整数空间。许多优化编译器将优化memcpy()
并将其替换为在x84浮点和整数寄存器之间传输数据的硬件指令,但您可能需要仔细检查生成的机器代码以确保性能如果性能这些行动很重要。