Windows / msvc 上的 clang:为什么在 FE_UPWARD 下 printf("%.1f\n", 0.0) 打印 0.1 而不是 0.0?
clang on Windows / msvc: why under FE_UPWARD printf("%.1f\n", 0.0) prints 0.1 instead of 0.0?
示例代码(t928.c):
#include <stdio.h>
#include <fenv.h>
#if _MSC_VER && ! __clang__
#pragma fenv_access (on)
#else
#pragma STDC FENV_ACCESS ON
#endif
int main(void)
{
int i = fesetround( FE_UPWARD );
if ( ! i )
{
printf( "%.1f\n", 0.0 );
}
return 0;
}
调用:
$ clang t928.c -Wall -Wextra -std=c11 -ffp-model=strict -pedantic && ./a.exe
0.1
$ cl t928.c /std:c11 /Za /fp:strict && ./t928.exe
0.1
版本:
$ clang --version
clang version 12.0.0
$ cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29913 for x64
UPD20210824。用户 chux - 恢复 Monica 假设:
Some compilers have trouble properly including FP support when there is no FP activity in user code. Try adding some.
这是它:
int main(void)
{
float f1 = 0.0f;
float f2 = 0.0f;
float f3 = 0.0f;
int i = fesetround(FE_UPWARD);
if ( ! i )
{
printf("%.1f\n", 0.0);
}
f3 = f1 + f2;
printf("%.1f\n", f3);
return 0;
}
调用:
$ gcc t928.c -Wall -Wextra -std=c11 -pedantic && ./a.exe
t928.c:6: warning: ignoring '#pragma STDC FENV_ACCESS' [-Wunknown-pragmas]
6 | #pragma STDC FENV_ACCESS ON
|
0.0
0.0
$ cl t928.c /std:c11 /Za /fp:strict && ./t928.exe
0.1
0.1
$ clang12 t928.c -Wall -Wextra -std=c11 -ffp-model=strict -pedantic && ./a.exe
0.1
0.1
UPD20210831。微软的回答:
This is an issue in the Universal CRT with our FE_UPWARD and FE_DOWNWARD rounding modes where some numbers will round up as though they had additional non-zero digits after them. This will be fixed in the Universal CRT and will be included in a future release of the Windows OS and Windows SDK.
示例代码(t928.c):
#include <stdio.h>
#include <fenv.h>
#if _MSC_VER && ! __clang__
#pragma fenv_access (on)
#else
#pragma STDC FENV_ACCESS ON
#endif
int main(void)
{
int i = fesetround( FE_UPWARD );
if ( ! i )
{
printf( "%.1f\n", 0.0 );
}
return 0;
}
调用:
$ clang t928.c -Wall -Wextra -std=c11 -ffp-model=strict -pedantic && ./a.exe
0.1
$ cl t928.c /std:c11 /Za /fp:strict && ./t928.exe
0.1
版本:
$ clang --version
clang version 12.0.0
$ cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29913 for x64
UPD20210824。用户 chux - 恢复 Monica 假设:
Some compilers have trouble properly including FP support when there is no FP activity in user code. Try adding some.
这是它:
int main(void)
{
float f1 = 0.0f;
float f2 = 0.0f;
float f3 = 0.0f;
int i = fesetround(FE_UPWARD);
if ( ! i )
{
printf("%.1f\n", 0.0);
}
f3 = f1 + f2;
printf("%.1f\n", f3);
return 0;
}
调用:
$ gcc t928.c -Wall -Wextra -std=c11 -pedantic && ./a.exe
t928.c:6: warning: ignoring '#pragma STDC FENV_ACCESS' [-Wunknown-pragmas]
6 | #pragma STDC FENV_ACCESS ON
|
0.0
0.0
$ cl t928.c /std:c11 /Za /fp:strict && ./t928.exe
0.1
0.1
$ clang12 t928.c -Wall -Wextra -std=c11 -ffp-model=strict -pedantic && ./a.exe
0.1
0.1
UPD20210831。微软的回答:
This is an issue in the Universal CRT with our FE_UPWARD and FE_DOWNWARD rounding modes where some numbers will round up as though they had additional non-zero digits after them. This will be fixed in the Universal CRT and will be included in a future release of the Windows OS and Windows SDK.