C++变量和调试器之间的值不同

C++ different values between variables and debugger

本文关键字:之间 变量 调试器 C++      更新时间:2023-10-16

我在C++中使用Visual Studio。

我接到一个奇怪的案子。这是我的代码(简化版):

Point GetPoint(/*parameters*/)
{
float Ax = 149; //Value depending on parameters
float Ay = 20;
float Bx = 29;
float By = 19;
double pAB = (Ay - By) / (Ax - Bx);
double Sx = Cx;
double Sy = pAB * (Cx - Ax) + Ay;
// Sy = (20 - 19) / (149 - 29) * (29 - 149) + 20.0
// => Sy = 1 / 120 * -120 + 20
// => Sy = -1 + 20

return new Point(static_cast<int>(Sx), static_cast<int>(Sy));
}

我原以为Sy=19,但我的点值是18。我启动调试器来理解,我发现了这个:

(Ay-By)/(Ax-Bx)=0.00833333284

(20.0-19.0)/(149.0-29.0)=0.0083333333333333332

pAB=0.0083333337679505348

和:

(20.0-19.0)/(149.0-29.0)*(29.0-149.0)+20.0=19

Sy=18.999999947845936

最终演员阵容将我的分数设置为18(sy<19)。但C#中的相同代码给了我19分。为什么这些差异?我怎样才能拿到19分?

C++和C#是不同的语言,有不同的规则和编译器。由于浮点在定义上是不精确的,任何细微的差异都可能导致您看到的值不同。

我根本不知道C#规则,但在C++中,请注意,当您将pAB键入为double时,您实际上是在float中计算它的值(因为AxAyBxBy都是float),只有在这之后,值才会提升为double。换句话说,在这里使用double不会获得任何精度。也许这里的C#规则不同,不知道。

无论如何,如果你确保pAB是在double中计算的,你就会得到这些特定数字的确切值:[实际示例],与[不变代码]相比。

确保在double中实际计算出double值可能是正确的解决方案。尽管如此,由于浮点不精确的,并且使用其他值可能会"失败",如果您想要舍入行为,我建议使用std::round而不是强制转换为int