HAS_SUBNORM is 0: "subnormal results" 是四舍五入前确定还是四舍五入后确定?

HAS_SUBNORM is 0: "subnormal results" are determined before rounding or after rounding?

C11, 5.2.4.2.2 浮动类型的特点 , 10, 脚注26:

Characterization as absent is intended if no floating-point operations produce subnormal results from non-subnormal inputs, even if the type format includes representations of subnormal numbers.

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

测试表明,一些实现在舍入之前执行,一些实现在舍入之后执行。

这是测试:

#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 不一致的实现可以自由地做他们想做的事。

没有标准来管理选择将次正规值清零的实现是否基于四舍五入前的数学结果是次正规的还是四舍五入的结果是次正规的。

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

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