首页 > 解决方案 > 使用基于 LLVM 的编译器的算术运算结果不正确

问题描述

代码:

float fff = 255.0f;
float a0 = (fff / 255.0f) * 100.0f;

如果我使用基于 LLVM 的编译器(例如 Intel C++ 编译器或 clang)变量a0等于 100.000008,但如果我使用 g++ 编译器我会得到正确的结果 - 100。为什么基于 LLVM 的编译器会返回错误的结果?如何解决?我不能只切换到 g++ '因为这个有 LLVM 编译器没有的其他错误。

标签: c++floating-pointllvm

解决方案


我对 LLVM 编译器了解不多,但你得到 100.000008 很奇怪,因为你只有整数,即使在中间结果中也是如此。但是,即使使用 G++,由于计算中的(二进制)舍入误差,您仍然不应依赖浮点类型计算的准确结果,而常规类型并非如此(注意常规类型 - 我的意思是也就是说你不会有舍入但截断 - 浮点部分被忽略)例如,尝试在 g++ 中使用 0.1,你会注意到结果不是 0.1(如果你通过调试器查看或将 0.1f 与 0.1 进行比较,cout或 printf 不会显示足够的小数) 舍入错误

现在,如果您想比较 2 个浮点数而不查看绝对差是否低于 epsilon,我建议您使用常规 int 类型乘以某个预分频器 (x10^n),然后使用例如最后 3 位的数字作为浮点部分,例如,不是比较伏特,而是比较毫伏或微伏,然后在您要打印结果时在最后删除预分频器(在此之前重铸为浮点/双倍)。


推荐阅读