Windows下clang/msvc开启FE_UPWARD时printf(%.1f,0.0)输出0.1问题
Windows平台clang/MSVC设置
FE_UPWARD舍入模式后printf输出异常问题说明 在Windows平台使用clang或MSVC编译器时,设置浮点舍入模式为FE_UPWARD后,调用printf("%.1f\n", 0.0)会输出0.1而非预期的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
2021年8月24日更新
用户chux - Reinstate Monica提出猜想:
部分编译器在用户代码无浮点运算操作时,可能无法正确加载浮点支持模块,建议添加浮点运算代码尝试复现。
补充浮点运算后的测试代码
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
2021年8月31日微软官方答复
该问题是通用CRT(Universal CRT)的实现缺陷,在FE_UPWARD和FE_DOWNWARD舍入模式下,部分数值会被判定为末尾存在额外非零位而被错误舍入。该缺陷将在通用CRT中修复,随后续Windows操作系统和Windows SDK版本发布。
内容的提问来源于stack exchange,提问作者pmor
相关产品推荐
相关产品推荐

