#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
изключено не можем да разчитаме наfesetround()
върната стойност поради UB? В примера по-гореfesetround()
[неправилно] връща0
(т.е. посоката на закръгляване е зададена успешно), но от резултатите виждаме, че посоката на закръгляване не е зададена. - person pmor   schedule 13.09.2020