FLT_ROUNDS 与 fesetround() / fegetround() 的行为

问题描述 投票:0回答:1

关于

FLT_ROUNDS
中声明的
<float.h>
宏,C 标准中的脚注指出:

浮点加法的舍入模式由实现定义的 FLT_ROUNDS 值来表征:23)

-1 不确定

0 走向零

1 到最接近的

2 朝向正无穷

3 朝向负无穷

23) 对

FLT_ROUNDS
的评估可以通过
fesetround
中的函数
<fenv.h>
正确反映舍入模式的任何执行时间变化。

用一个小示例程序尝试一下:

#include <float.h>
#include <fenv.h>
#include <stdio.h>

#pragma STDC FENV_ACCESS ON

int main()
{
    printf( "Initial FLT_ROUND:  %d\n", FLT_ROUNDS );
    printf( "Initial fegetround: %d\n\n", fegetround() );
    fesetround( FE_TOWARDZERO );
    printf( "Current FLT_ROUND:  %d\n", FLT_ROUNDS );
    printf( "Current fegetround: %d\n", fegetround() );
}

编译:

gcc -std=c11 testme.c -o testme -lm

我在 Linux 上得到以下输出:

Initial FLT_ROUND:  1
Initial fegetround: 0

Current FLT_ROUND:  1
Current fegetround: 3072

在 Cygwin 上:

Initial FLT_ROUND:  1
Initial fegetround: 0

Current FLT_ROUND:  1
Current fegetround: 3

鉴于标准的声明,我会期待

...
Current FLT_ROUND:  0
...

这是不合格的实现,还是我错误地理解了标准脚注?

FWIW,在 Android / Termux 上尝试同样的操作给了我:

Initial FLT_ROUND:  1
Initial fegetround: 0

Current FLT_ROUND:  0
Current fegetround: 3

这让我怀疑 Linux 和 Cygwin 上的实现都有错误......?

c floating-point language-lawyer fenv
1个回答
0
投票

这是GCC Bug 30569

GCC 将此记录为“实现定义的行为”

以 FLT_ROUNDS 的非标准值为特征的舍入行为(C90、C99 和 C11 5.2.4.2.2)。

 GCC does not use such values.

Termux 使用 BSD libc 和 clang“伪装”为 GCC,这解释了 Android 上符合标准的行为。

© www.soinside.com 2019 - 2024. All rights reserved.