【问题标题】:Are there invalid floating point states/values?是否存在无效的浮点状态/值?
【发布时间】:2021-12-26 15:27:46
【问题描述】:

我知道存在 NaN 和其他各种特殊情况。但是还有其他完全无效的未使用的二进制值吗?

例如,IEEE 754 确实允许 -0。但如果没有,那么二进制值10000000000000000000000000000000 将无效。是否还有其他未处理的边缘情况?

【问题讨论】:

  • 不。正规数、次正规数、+-Inf、+-Zero 和 NaN:s 构成了整个 IEEE-754 编码空间。

标签: floating-point ieee-754 low-level


【解决方案1】:

IEEE-754 二进制和十进制交换格式没有任何未定义的位模式。 (对于十进制,IEEE 754-2008 第 3.5.2 条中的编码部分为所有位字符串指定了值 [包括 NaN “值”]。一些位字符串被指定为非规范,但都有定义的值。)

英特尔的“双扩展精度”格式确实有未定义的位模式。 英特尔 64 和 IA-32 架构软件开发人员手册,2017 年 12 月,8.2.2“不支持的双扩展精度浮点编码和伪非正规”说:

双扩展精度浮点格式允许许多不属于表 4-3 中所示类别的编码。表 8-3 显示了这些不受支持的编码。 Intel 287 数学协处理器支持其中一些编码;但是,它们中的大多数不受 Intel 387 数学协处理器和更高版本的 IA-32 处理器的支持。由于 IEEE 标准 754 的最终版本中取消了这些编码,因此不再支持这些编码。

具体来说,以前称为伪 NaN、伪无穷大和非正规数的编码类别不受支持,不应用作操作数值。当这些编码作为操作数遇到时,Intel 387 数学协处理器和更高版本的 IA-32 处理器会生成无效操作异常。

表 8-3 显示了未定义的模式在整数位(有效数的前导位,显式存储在 Intel 格式的专用“整数”一位字段中)和非零指数场。当指数字段全为 1 时,这些是伪 NaN(如果分数字段非零)或伪无穷大(如果分数字段为零)。当指数字段既不是全1(也不是全零)时,这些都是非正态的。

(当整数位为零且指数域全为零时,该数为普通次正规数;零整数位正确匹配指数域隐含的零。)

其他供应商和各方当然也可能有自己的格式,但未定义位模式。

【讨论】:

  • 也许值得注意的是,虽然十进制交换格式没有无效的位模式,但它们确实有一些非规范的位模式(尽管确切地说哪些位模式是非规范取决于有效位是使用二进制编码还是十进制编码),并且存在从非规范位模式到规范等效项的显式映射。 大多数 操作被指定为接受非规范位模式,但只发出规范位模式。 (某些操作,例如 copySign 和朋友,可以为非规范输入生成非规范结果。)
  • @MarkDickinson:谢谢。我刚刚有时间阅读十进制编码部分,在我看来,每个位字符串都被指定为具有某些值,即使某些位字符串是非规范的。我更新了答案。
【解决方案2】:

在 80 位扩展中,存在“未规范化”的数字。在该格式中,完整的尾数被存储,包括前导 1 位。如果未设置该位,则这是一个不应发生的“非标准化”数字。在极端情况下,您可能会得到一个具有大指数的零(尾数全为零)。

不过,这将得到正确处理。如果您遇到将这种异常格式转换为规范化或非规范化数字的硬件异常,我不会感到惊讶。并且某些处理器上不存在 80 位扩展。

除此之外,一切都是允许的。显然,您有“信号 NaN”,如果您使用它们,应该创建一些信号,但这是预期的。由于您的编译器,未初始化的内存可能会产生副作用(未初始化的内存始终是未定义的行为),例如,这与 unsigned int 相同。但是没有位模式会给你带来麻烦。

【讨论】:

  • 仍然可以正确处理。 - 通过什么? Eric 的回答引用了文档说 387 HW(以及与其兼容的现代 CPU)会将非规范化的 80 位浮点数(次规范除外)视为无效,从而引发 FP-invalid 异常。 (因此产生 NaN 输出或捕获,取决于是否屏蔽了 FP 异常。)
猜你喜欢
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多