当我在发布模式下编译应用程序时,我得到不正确的除法结果 40.0/5 = 7。在调试编译中它是正确的,结果是 8
我试图投射到双倍,从双倍到整数,没有abs((等,但没有运气。我知道这一定与计算机上浮点数学的怪异有关,但我不知道究竟是什么。我还通过代码下方的 qDebugs(( 在控制台上记录了这些值 - 除了初始步骤外,一切看起来都不错。
//somewhere in code
double tonnageToRecover = 0.5;//actually, its QDoubleSpinBox->value(), with 0.5 step set. Anyway, the value finally reduces to 0.5 every time
double tonnagePerArmorPoint = 0.0125;//taken from .json
int minimumArmorDelta = 5;//taken from .json
...
//palace where the calculations are preformed
double armorPointsPerHalfTon = tonnageToRecover / tonnagePerArmorPoint;
int steps = abs(static_cast<int>(armorPointsPerHalfTon / minimumArmorDelta));
qDebug() << "armorPointsPerHalfTon = " << armorPointsPerHalfTon;
qDebug() << "tonnagePerArmorPoint = " << tonnagePerArmorPoint;
qDebug() << "steps initial = " << steps;
qDebug() << "minimumArmorDelta = " << minimumArmorDelta;
两个第一师零件都是双精度型,吨位恢复= 0.5,吨位每装甲点= 0.0125,结果是40,这是可以的最小装甲增量为 int = 5
那么为什么 40/5 不是 8??
编译器 - MinGW 32 5.3.0,来自 Qt 5.11 包
截图:释放调试
@Julian我也怀疑这一点,但我如何克服这个障碍?将尝试将步骤更改为双精度,然后再次转换为 int。RESUT:仍然不起作用:/
我找到了一个解决方案,但我不知道它现在为什么有效。当前代码它:
double armorPointsPerHalfTon = tonnageToRecover / tonnagePerArmorPoint;
// int aPHT = (int)armorPointsPerHalfTon;
// double minDelta = 5.0;//static_cast<double>(minimumArmorDelta);
QString s(QString::number(abs(armorPointsPerHalfTon / minimumArmorDelta)));
int steps = abs(armorPointsPerHalfTon / minimumArmorDelta);
#define myqDebug() qDebug() << fixed << qSetRealNumberPrecision(10)
myqDebug() << "tonnageToRecover = " << tonnageToRecover;
myqDebug() << "tonnagePerArmorPoint = " << tonnagePerArmorPoint;
myqDebug() << "armorPointsPerHalfTon = " << armorPointsPerHalfTon;
//myqDebug() << "aPHT = " << aPHT;//this was 39 in Release, 40 in Debug
myqDebug() << "steps initial = " << steps;
myqDebug() << "string version = " << s;
myqDebug() << "minimumArmorDelta = " << minimumArmorDelta;// << ", minDelta = " << minDelta;
#undef myqDebug
我想创建该 QString 会刷新一些东西,这就是为什么现在计算步骤是正确的。但是,字符串的值"7"不正确。
您的基本问题是您正在截断。
假设实数算术会给出正好 8 的答案。浮点运算将给出非常接近 8 的答案,但由于舍入误差,在任一方向上都可能与它不同。如果浮点答案略大于 8,则截断会将其更改为 8。如果它甚至略小于 8,截断会将其更改为 7。
我建议写一个关于如何避免截断的新问题,并讨论你为什么要这样做。
猜,原因是armorPointsPerHalfTon / minimumArmorDelta
在发布版本中可能不是 8,而是实际上是 7.999999999。然后,此值通过 int-cast 更改为 7。
因此,如果调试版本计算armorPointsPerHalfTon / minimumArmorDelta = 8.0000001
,则结果为 static_cast<int>(armorPointsPerHalfTon / minimumArmorDelta) = 8
。
调试/发布产生不同的结果(按机器精度顺序(也就不足为奇了,因为在发布版本中进行了多次优化。
编辑:如果它符合您的要求,您可以使用std::round
将双精度四舍五入到最接近的整数,而不是截断小数。