0

C11,5.2.4.2.2 浮动类型的特征 <float.h>,10,脚注 26:

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

这里的“次正常结果”是在四舍五入之前还是在四舍五入之后确定的?

测试表明,有些实现是在舍入之前做的,有些实现是在舍入之后做的。

这是测试:

#if FLT_HAS_SUBNORM == 0
int subnorm_determ_method( void )
{
    volatile float f1 = FLT_MIN; /* 1.17549435e-38f */
    volatile float f2 = 1.0000001f;
    volatile float f3;
    int r;

    r = fesetround(FE_UPWARD);
    if ( r != 0 )        return -1; /* error: fesetround(FE_UPWARD) failed */
    f3 = f1 / f2;
    if ( f3 == FLT_MIN ) return 0; /* "subnormal results" are determined after rounding */
    if ( f3 == 0.0f )    return 1; /* "subnormal results" are determined before rounding */
    return -2; /* error: unexpected result */
}
#endif

UPD(在完成更多研究/实验之后)。

  1. FTZ 逻辑的确切执行位置与这个问题无关:无论是在舍入前还是舍入后执行 FTZ 逻辑,舍入(交付)的结果都不是次正规的。
  2. 如果一个实现不支持次正规数,那么这种实现不符合 IEEE 754。因此,这种实现可以自由选择在哪一步执行 FTZ 逻辑。实验证实: FTZ=1(或永久 FTZ=1)配置的不同实现可能在不同的步骤执行 FTZ 逻辑,因此产生不同的结果:±0.0±<TYPE_PREFIX>_MIN.
  3. 额外:在 FTZ=1 的情况下引发浮点异常:与 2 中的情况相同。:IEEE 754 不符合标准的实现可以自由地做他们想做的事。
4

1 回答 1

1

没有标准根据舍入前的数学结果是否低于正常值或舍入结果是否低于正常值来管理选择将次正规值刷新为零的实现是否这样做。

无论实现在这方面做出何种选择,引用的文本都与交付的结果有关。如果没有浮点运算产生次规范的结果,则打算将其表征为不存在。

请注意,实现是否选择在舍入之前或之后将次正规值清零与此无关:在任何一种情况下,实现都不会提供次正规结果。在四舍五入后刷新次正规的一个将所有结果刷新为零,并且只有那些本来是次正规的结果。在舍入之前刷新的结果将所有本来不正常的结果和一些本来正常的结果刷新为零。两者都不会提供低于正常水平的结果。

于 2021-07-14T01:58:19.630 回答