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

时间:2017-10-27 10:36:47

标签: c++

我使用Visual Studio在C ++中工作。

我遇到了一个奇怪的案子。有我的代码(简化版):

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?

1 个答案:

答案 0 :(得分:1)

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

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

无论如何,如果您确保在double中计算pAB,则会获得具有这些特定数字的确切值:[live example],与[the unchanged code]相比。

确保在double中实际计算double值可能是正确的解决方案。然而,由于浮点 不精确,可能会失败&#34;对于其他值,如果您想要舍入行为,我建议使用std::round而不是转换为double