Я хотел бы вычислить сумму, округленную, из двух двоичных чисел IEEE 754. С этой целью я написал программу C99 ниже:
#include <stdio.h>
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
int main(int c, char *v[]){
fesetround(FE_UPWARD);
printf("%a\n", 0x1.0p0 + 0x1.0p-80);
}
Однако, если я компилирую и запускаю свою программу с различными компиляторами:
$ gcc -v
…
gcc version 4.2.1 (Apple Inc. build 5664)
$ gcc -Wall -std=c99 add.c && ./a.out
add.c:3: warning: ignoring #pragma STDC FENV_ACCESS
0x1p+0
$ clang -v
Apple clang version 1.5 (tags/Apple/clang-60)
Target: x86_64-apple-darwin10
Thread model: posix
$ clang -Wall -std=c99 add.c && ./a.out
add.c:3:14: warning: pragma STDC FENV_ACCESS ON is not supported, ignoring
pragma [-Wunknown-pragmas]
#pragma STDC FENV_ACCESS ON
^
1 warning generated.
0x1p+0
Это не работает! (Я ожидал результата 0x1.0000000000001p0).
В самом деле, вычисление было выполнено во время компиляции в стандартном раунде до ближайшего режима:
$ clang -Wall -std=c99 -S add.c && cat add.s
add.c:3:14: warning: pragma STDC FENV_ACCESS ON is not supported, ignoring
pragma [-Wunknown-pragmas]
#pragma STDC FENV_ACCESS ON
^
1 warning generated.
…
LCPI1_0:
.quad 4607182418800017408
…
callq _fesetround
movb $1, %cl
movsd LCPI1_0(%rip), %xmm0
leaq L_.str(%rip), %rdx
movq %rdx, %rdi
movb %cl, %al
callq _printf
…
L_.str:
.asciz "%a\n"
Да, я видел предупреждение, выпущенное каждым компилятором. Я понимаю, что включение или отключение применимых оптимизаций в масштабе линии может быть сложным. Мне бы хотелось, если бы это было возможно, отключить их в масштабе файла, что было бы достаточно для решения моего вопроса.
Мой вопрос: какие параметры командной строки следует использовать с GCC или Clang, чтобы скомпилировать блок компиляции C99, который содержит код, предназначенный для выполнения в режиме округления FPU, отличном от стандартного?
Экскурс
При изучении этого вопроса я нашел эту страницу соответствия GCC C99, содержащую запись ниже, что я просто оставлю здесь, если кто-то другой находит это забавным. Grrrr.
floating-point | | environment access | N/A | Library feature, no compiler support required. in <fenv.h> | |