Floating point 我们可以在自定义标志中使用任何浮点值吗?

Floating point 我们可以在自定义标志中使用任何浮点值吗?,floating-point,nan,ieee-754,Floating Point,Nan,Ieee 754,我用LINUX RHEL 64位编写代码,并使用C++98 我有一个浮点值数组,我想“标记”一些值为“无效”。一种可能的解决方案是使用另一个位数组来判断相应的值是否有效 我想知道我们是否可以使用任何特殊的双精度值。链接上说有很多NaN值。我们可以使用为我的问题保留的任何值吗 我只需要有效负载中的一位,就我的定义而言,指示双精度值是否“有效”。输入的double值可以包含NaN,但我假设它不会使用任何有效负载 双精度值将以二进制模式保存到文件中(逐位保存双精度值) 然后,代码还以二进制模式从文件

我用LINUX RHEL 64位编写代码,并使用C++98

我有一个浮点值数组,我想“标记”一些值为“无效”。一种可能的解决方案是使用另一个位数组来判断相应的值是否有效

我想知道我们是否可以使用任何特殊的双精度值。链接上说有很多NaN值。我们可以使用为我的问题保留的任何值吗

  • 我只需要有效负载中的一位,就我的定义而言,指示双精度值是否“有效”。输入的double值可以包含NaN,但我假设它不会使用任何有效负载
  • 双精度值将以二进制模式保存到文件中(逐位保存双精度值)
  • 然后,代码还以二进制模式从文件中读取数据
  • 对于从文件中读取的每个双精度值,在进行任何其他计算之前,我们首先检查有效负载中设置的位是否有效

一般来说,IEEE-754允许但不要求支持NaN有效载荷。然而,这里我们有x64系统的具体情况,AMD和Intel的相关处理器支持NaN有效负载

IEEE Std 754-2008进一步规定,对于NaN编码,尾数的最重要部分位区分安静和信令NaN。这对应于单精度和双精度类型的最高有效存储尾数位。因此,不能将此位用于自定义编码目的。x64处理器根据各种异常情况生成特定的QNaN,QNaN编码的符号位用于此,因此符号位也禁止自定义基于NaN的标记

各种工具链提供了宽松的、不符合IEEE-754标准的“快速数学”,其中无法保证NAN的传播。您需要使用最严格的浮点设置(例如英特尔编译器
-fp model strict
)进行编译,以确保自定义标记不会丢失。各种软件环境使用NaN有效载荷对导致创建NaN的特定事件进行编码(苹果的SANE就是此类系统的历史例子)。根据我的经验,这样的系统通常利用NaN编码尾数部分的低阶位

这表明,高阶尾数位,例如IEEE-754双精度数字的50:48位或IEEE-754单精度数字的21:19位,是在NaN编码中放置自定义标志的最佳位置(如前所述,保留未触及的最重要尾数位)。通过
float
double
类型传输数据可能会有问题,因为x64体系结构规范没有规定在不同浮点类型之间传播NaN有效载荷,我可以通过查看AMD的原始x64体系结构规范和英特尔最新文档来了解这一点。纯粹根据经验,我发现NaN有效负载的处理方式是,单精度编码的位[n]显示为双精度编码的位[n+29],反之亦然


考虑到编程语言的限制,最好使用
memcpy()
在浮点和无符号整数表示之间进行转换,并执行所需的位级操作来设置、清除和测试整数空间中的自定义NaN有效负载。许多优化编译器将优化
memcpy()
并用在x84浮点寄存器和整数寄存器之间传输数据的硬件指令取代它,但如果这些操作的性能很重要,您可能需要对生成的机器代码进行双重检查,以确保这一点。

请注意,NaN“有效负载”并非所有支持NAN的平台都支持NAN。IEEE-754允许使用单个规范NaN。实际上,在大多数平台上支持NANNEXY负载,通常可以通过C和C++的标准库函数实现定义,NANIN C++在C++ 11中工作。对于旧C++,我们只有STD::NoimiCiLime::QuielyNo()。而且它不支持设置有效负载。通过位掩码设置是否安全…?是的,您可以使用位操作访问NaN编码,前提是考虑了有关类型重新解释的正常警告。我假设C++11是人们在这一点上使用的。我认为如果你能澄清你计划使用什么编程语言和操作系统平台,你需要多少不同的编码,以及你计划如何使用这些编码,这将有助于解决这个问题(例如,是否不仅需要设置,还需要检查程序内部使用的特定编码?我认为没有C/C++标准函数用于此)@njuffa我更新了我的原始问题以解决您的问题。在问题中提及目标平台会很有帮助,因为一些软件环境已经为自己的目的预先定义了一些可用的NaN编码。我在相关问题中给出的具体示例是各种苹果平台。对于单精度浮点(C中的浮点类型),使用这些高有效位是否仍然安全?@JoeC显然,单精度尾数的高阶位位于不同的位置。我将把它添加到答案中以避免歧义。如果double中的位[n+29]映射到位[n]在float中,这是否意味着at的位使用仅适用于double?它使用第8-15位,根据上述映射,这些位在float中不存在。或者,苹果系统中不允许进行转换?@JoeC我不知道苹果SANE系统如何处理浮点转换。它可能与底层硬件的功能有关如我在回答中所述,我关于有效载荷位映射的发现是经验性的,仅适用于x64处理器。数据类型之间的NaN传播行为可能完全不同