VS2019环境下C++使用long double计算结果及精度不符合预期求助
问题原因分析
1. MSVC编译器对long double的默认实现规则
- 你观测到
LDBL_DIG = 15属于正常现象,Visual Studio使用的MSVC编译器在x86、x64架构下,默认将long double类型实现为和double完全一致的64位双精度浮点数,和GCC等编译器默认采用80位扩展精度long double的规则不同,所以精度和double没有差异,自然c的输出结果和b完全相同。 - 如果你需要启用80位扩展精度的
long double,可以在项目属性的【C/C++ -> 命令行】中添加/Qlong_double编译参数,开启后LDBL_DIG会变为18,long double的精度也会符合你的预期。
2. 代码存在隐式类型转换导致的精度损失
你给long double变量赋值的逻辑存在隐式精度损失问题:
long double c = 10.0 / 3;
这里的10.0是double类型的常量,所以10.0 / 3的计算全程按照double精度执行,结果先存储为double再隐式转换为long double,等于精度在赋值前就已经损失,后续再做乘法也无法拿到更准确的结果。正确写法需要给常量加L后缀,指定用long double类型执行计算:
long double c = 10.0L / 3; c = c * 10000000000000000000.0L;
3. 浮点数本身的精度限制导致结果偏差
float类型的有效十进制位数仅为6~7位(对应你输出的FLT_DIG=6),乘上1e19这么大的数值后,存储误差会被放大到十亿级,所以a的输出结果从第8位开始就出现偏差属于正常现象。double类型的有效十进制位数为15~17位(对应DBL_DIG=15),你可以核对b的输出结果33333333333333336240.000000,前面15位333333333333333是完全准确的,后续位数超出了double的精度范围,属于浮点数存储无限循环小数的固有误差,不属于代码错误。
内容的提问来源于stack exchange,提问作者MarioM
相关产品推荐
相关产品推荐

