#include <stdio.h>
#include <stdint.h>
#include <fenv.h>
#include <math.h>
int main()
{
typedef union { uint32_t u; float f; } ufloat;
ufloat val;
float arg = 2401.999999;
int r;
r = fesetround(FE_DOWNWARD);
val.f = sqrtf(arg);
printf ("FE_DOWNWARD %22.13a [0x%x] %d\n", val.f, val.u, r);
r = fesetround(FE_TONEAREST);
val.f = sqrtf(arg);
printf ("FE_TONEAREST %22.13a [0x%x] %d\n", val.f, val.u, r);
r = fesetround(FE_TOWARDZERO);
val.f = sqrtf(arg);
printf ("FE_TOWARDZERO %22.13a [0x%x] %d\n", val.f, val.u, r);
r = fesetround(FE_UPWARD);
val.f = sqrtf(arg);
printf ("FE_UPWARD %22.13a [0x%x] %d\n", val.f, val.u, r);
return 0;
}
Хост: Win10 x64.
Полученные результаты:
Дело 1.
$ clang t2.c -o t2.clang.exe && ./t2.clang.exe FE_DOWNWARD 0x1.8814e60000000p+5 [0x42440a73] 0 FE_TONEAREST 0x1.8814e60000000p+5 [0x42440a73] 0 FE_TOWARDZERO 0x1.8814e60000000p+5 [0x42440a73] 0 FE_UPWARD 0x1.8814e60000000p+5 [0x42440a73] 0 $ clang --version clang version 8.0.1 (tags/RELEASE_801/final)
Случай 2.
$ gcc t2.c -o t2.gcc.exe && ./t2.gcc.exe FE_DOWNWARD 0x1.8814e60000000p+5 [0x42440a73] 0 FE_TONEAREST 0x1.8814e60000000p+5 [0x42440a73] 0 FE_TOWARDZERO 0x1.8814e60000000p+5 [0x42440a73] 0 FE_UPWARD 0x1.8814e60000000p+5 [0x42440a73] 0 $ gcc --version gcc (GCC) 10.2.0
Случай 3.
cl t2.c && t2 Microsoft (R) C/C++ Optimizing Compiler Version 19.25.28611 for x64 ... FE_DOWNWARD 0x1.8814e40000000p+5 [0x42440a72] 0 FE_TONEAREST 0x1.8814e60000000p+5 [0x42440a73] 0 FE_TOWARDZERO 0x1.8814e40000000p+5 [0x42440a72] 0 FE_UPWARD 0x1.8814e60000000p+5 [0x42440a73] 0
Случай 4.
cl t2.c && t2 Microsoft (R) C/C++ Optimizing Compiler Version 19.25.28611 for x86 ... The system cannot execute the specified program. Pop-up window appears: "Virus & thread protection: Windows Defender Antivirus found threats. Get details."
Случай 5.
wandbox.org: gcc HEAD 11.0.0 20200 $ gcc prog.c -Wall -Wextra -std=c99 "-lm" FE_DOWNWARD 0x1.8814e40000000p+5 [0x42440a72] 0 FE_TONEAREST 0x1.8814e60000000p+5 [0x42440a73] 0 FE_TOWARDZERO 0x1.8814e40000000p+5 [0x42440a72] 0 FE_UPWARD 0x1.8814e60000000p+5 [0x42440a73] 0
Случай 6.
wandbox.org: clang HEAD 12.0.0 $ clang prog.c -Wall -Wextra -std=gnu11 "-lm" FE_DOWNWARD 0x1.8814e40000000p+5 [0x42440a72] 0 FE_TONEAREST 0x1.8814e60000000p+5 [0x42440a73] 0 FE_TOWARDZERO 0x1.8814e40000000p+5 [0x42440a72] 0 FE_UPWARD 0x1.8814e60000000p+5 [0x42440a73] 0
Вопросы:
- Почему между компиляторами разные результаты (
0x42440a72
и0x42440a73
)? - Как получить одинаковые результаты между компиляторами?
<pre>code</pre>
)! - person pmor   schedule 13.09.2020FENV_ACCESS
(C 2018 7.6.1 2). Вы можете включить его с помощью#pragma STDC FENV_ACCESS ON
в компиляторах, которые его поддерживают. - person Eric Postpischil   schedule 13.09.2020FENV_ACCESS
off мы не можем полагаться на возвращаемое значениеfesetround()
из-за UB? В приведенном выше примереfesetround()
действительно [ложно] возвращает0
(т. е. направление округления было успешно установлено), но из результатов мы видим, что направление округления не было задано. - person pmor   schedule 13.09.2020