【问题标题】:FLT_HAS_SUBNORM is 0: subnormal <op> normal can produce subnormal?FLT_HAS_SUBNORM 为 0:不正常 <op> 正常能产生不正常吗?
【发布时间】:2021-03-25 13:46:51
【问题描述】:

ISO/IEC 9899:202x (E) 工作草案 - 2020 年 2 月 5 日 C17..C2x N2479:

次正规数的存在与否由实现定义的 FLT_HAS_SUBNORM、DBL_HAS_SUBNORM 和 LDBL_HAS_SUBNORM 的值:

-1 不确定 27)

0 缺席(类型不支持次正规数)28)

存在 1 个(类型确实支持次正规数)

28) 如果没有浮点运算从非次正规输入中产生次正规结果,即使类型格式包括次正规数的表示,也打算将其表征为不存在。

换句话说,28) 说:if FLT_HAS_SUBNORM is 0, then any_normal &lt;op&gt; any_normal never produces subnormal

但是,由于存在from non-subnormal inputs,我们可以推断出if FLT_HAS_SUBNORM is 0, then some_subnormal &lt;op&gt; some_normal may produce subnormal。这很奇怪,因为:

  1. 它与characterization as absent(即FLT_HAS_SUBNORM is 0)兼容。
  2. may produce subnormal就算type does not support subnormal numbers

有人可以解释/解决这个奇怪的问题吗?

【问题讨论】:

  • 我没有发现问题。脚注 28 阐明“不支持”一词旨在包括类型确实支持它们但编译器不会自行生成它们的情况。也许这不是最好的措辞选择,但脚注似乎使情况变得清晰。但如果你故意喂它低于正常值,那么所有的赌注都没有了。
  • 我总是可以通过操作位或从文件中读取值来创建次正规表示。
  • @stark 有一个结论,如果FLT_HAS_SUBNORM(或DBL)为0,那么这样的manually constructedFP对象(通过类型双关、memcpy()、从文件读取等)导致UB .请参阅 stackoverflow.com/a/65296492/9881330。
  • 当我读到它时:DBL_MIN/4.0DBL_HAS_SUBNORM == 1 产生了一个次要的。我希望DBL_HAS_SUBNORM == 0 产生 0.0(四舍五入到最近)。然而pow(2.0, DBL_MIN_EXP - 2) 可能在这两种情况下都产生次正常,因为它是一个函数而不是一个操作。
  • @stark 更正:“......然后使用这种手动构造的 FP 对象作为输入执行 FP 操作似乎会导致 UB”。

标签: c


【解决方案1】:

FLT_HAS_SUBNORM is 0: subnormal &lt;op&gt; normal可以产生subnormal

是的,但它会在 UB 下。

=== 为什么会在UB下===

C 标准对FLT_HAS_SUBNORM is 0 的情况相当克制。关于FLT_HAS_SUBNORM is 0 的所有内容是:

absent(类型不支持次正规数)

如果没有浮点运算从非次正规输入产生次正规结果,即使类型格式包括次正规数的表示,也打算将其表征为不存在。

可以解释为:

If FLT_HAS_SUBNORM is 0, then any_normal &lt;op&gt; any_normal never produces subnormal.

C 标准似乎省略了以下情况的明确行为定义(以问题形式表述):

如果FLT_HAS_SUBNORM is 0: 使用由手动构造的子范式表示的输入执行 FP 操作(通过联合使用类型双关、使用 memcpy()、从文件读取等)会导致未定义的行为 (UB)?

如果省略了行为的显式定义,那么根据C标准:

...未定义的行为在本文档中另有说明...通过省略任何明确的行为定义...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多