我使用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?
答案 0 :(得分:1)
C ++和C#是不同的语言,具有不同的规则和不同的编译器。由于浮点根据定义是不精确的,任何微妙的差异都可能导致您看到的不同值。
我根本不了解C#规则,但在C ++中,请注意,虽然您已将pAB
键入为double
,但您实际上正在float
中计算其值1}}(因为Ax
,Ay
,Bx
,By
都是float
s),只有在此之后才会提升为{{1} }}。换句话说,使用double
在这里没有获得任何精度。也许这里的C#规则不同,不知道。
无论如何,如果您确保在double
中计算pAB
,则会获得具有这些特定数字的确切值:[live example],与[the unchanged code]相比。
确保在double
中实际计算double
值可能是正确的解决方案。然而,由于浮点 不精确,可能会失败&#34;对于其他值,如果您想要舍入行为,我建议使用std::round
而不是转换为double
。