C# 带旋转矩阵的浮点误差
我一直在学习c#vector课程,以练习我的技能并自学,我遇到了一个相当令人恼火的问题C# 带旋转矩阵的浮点误差,c#,floating-point,double,C#,Floating Point,Double,我一直在学习c#vector课程,以练习我的技能并自学,我遇到了一个相当令人恼火的问题 public void Rotate (double rotation) { double xT; xT = x * Math.Cos (rotation * (Math.PI / 180)) - y * Math.Sin (rotation * (Math.PI / 180)); y = x * Math.Sin (rotation * (Ma
public void Rotate (double rotation)
{
double xT;
xT = x * Math.Cos (rotation * (Math.PI / 180)) - y * Math.Sin (rotation * (Math.PI / 180));
y = x * Math.Sin (rotation * (Math.PI / 180)) + y * Math.Cos (rotation * (Math.PI / 180));
x = xT; /*Figure out a better way to this*/
}
我知道这段代码很草率,但问题是当我尝试绕(1,0)180度简单旋转时,它返回的不是预期的(-1,0),而是(-1,-6.2343e-12)或类似的结果
我知道这是一个双打缺乏精确性的问题,但我想知道是否有办法让它仍然返回0而不是-12的数字
有什么方法可以做到这一点吗?使用向量的不可变结构通常更快/更干净
public struct Vector
{
readonly double x, y;
public Vector(double x, double y) { this.x=x; this.y=y; }
public Vector Rotate(double angle)
{
angle *= Math.PI/180;
double cos = Math.Cos(angle), sin=Math.Sin(angle);
return new Vector(
x*cos-y*sin,
x*sin+y*cos );
}
}
现在,就精度而言,除了在
System.Math
中使用trig函数外,别无选择。我建议在转换为弧度并使用到trig函数之前,通过将角度输入包装在-180..180
之间,对角度输入进行消毒 -0.0000000000062343
在我看来很像0。为什么它会困扰你?这真的打乱了你下面的计算吗?您可以将其汇总,但我不想麻烦。这是.NET中关于Sin/Cos的已知“问题”。请参阅中投票率最高的答案。我所能说的是,这就是双值的工作原理,如果你需要精确的零,那么你需要将所有的值四舍五入到11个小数点。这个问题对于应该为零的值来说尤其糟糕,因为离零最近的双精度值是+/-5e-324。我知道没有真正的方法来避免它,只是看到一些我知道的简单正确的答案之外的东西让我非常困扰,我希望有一种方法可以解决它。可能的重复我正在投票以另一种语言作为问题的重复来结束,因为这里的根本问题不是编程语言。这是否解决了“但我想知道是否有一种方法使它仍然返回0而不是-12”的问题。我说不,除非涉及包装,然后它将返回1e-17
Goodo。我喜欢使用不可变结构