当我在发布模式下编译我的应用程序时,我得到40.0 / 5 = 7的错误除法结果。在调试编译中它是正确的,结果是8
我试图强制转换为double,从double到int,没有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;
两个部分都是double类型,tonnageToRecover = 0.5,tonnagePerArmorPoint = 0.0125,结果是40,这是OK minimumArmorDelta是int = 5
那么为什么40/5不是8?
编译器 - MinGW 32 5.3.0,来自Qt 5.11 pack
@Julian我也怀疑,但我怎样才能克服这个障碍?将尝试将步骤更改为double,然后再次转换为int。重置:仍然不起作用:/
我找到了一个解决方案,但我不知道为什么它现在有效。目前的代码:
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.99999999在Release版本中。然后,此值通过int-cast更改为7。
因此,如果Debug版本计算armorPointsPerHalfTon / minimumArmorDelta = 8.0000001
,则结果为static_cast<int>(armorPointsPerHalfTon / minimumArmorDelta) = 8
。
调试/发布会产生不同的结果(按照机器精度的顺序)并不奇怪,因为发布版本中会出现一些优化。
编辑:如果它符合您的要求,您可以使用std::round
将您的double舍入到最接近的整数,而不是截断小数。