C# 带旋转矩阵的浮点误差

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

我一直在学习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 * (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。我喜欢使用不可变结构