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