C# 如何解决精度问题

C# 如何解决精度问题,c#,decimal,precision,unit-class-library,geometry-class-library,C#,Decimal,Precision,Unit Class Library,Geometry Class Library,我有几个类遵循处理单元的相同基本概念 下面是单元测试中使用的一个简单示例: [Test()] public void Angle_MathOperatorTest() { Angle a1 = new Angle(AngleType.Degree, 360); Angle a2 = new Angle(AngleType.Radian, Math.PI * 2); Angle addedAngle = a1 + a2;

我有几个类遵循处理单元的相同基本概念

下面是单元测试中使用的一个简单示例:

    [Test()]
    public void Angle_MathOperatorTest()
    {
        Angle a1 = new Angle(AngleType.Degree, 360);
        Angle a2 = new Angle(AngleType.Radian, Math.PI * 2);

        Angle addedAngle = a1 + a2;
        addedAngle.Degrees.ShouldBeEquivalentTo(720);

        Angle subtractedAngle = a1 - a2;
        subtractedAngle.Radians.ShouldBeEquivalentTo(0);
    }
我已经做了几个类似于这个演示的Angle类的类,涵盖了其他基本单元类型

向我透露我有精度问题的特定类是使用处理长度单位的类:
Dimension

我已经帮助构建了一个基本的几何图形库,利用这个维度类作为它的基本单位类型。例如,以下是Point类:

public class Point
{

    public Dimension X;

    public Dimension Y;

    public Dimension Z;
}
直线和其他形状具有诸如长度之类的特性,这些特性由使用此点类生成的标注和端点表示

当我试图判断这些线是否都平行时,问题就显而易见了。与此功能一样:

    /// <summary>
    /// checks to see whether every line is parallel
    /// </summary>
    /// <param name="passedLines">passed List of Lines</param>
    /// <returns></returns>
    public static bool AreAllParallel(this List<Line> passedLines)
    {

        for (int i = 0; i < passedLines.Count - 1; i++)
        {
            if (!passedLines[i].IsParallelTo(passedLines[i + 1]))
            {
                return false;
            }
        }

        return true;
    }
看起来确实是这样,但上面的内容更容易理解

return(Math.Abs(this.GetValue(this.InternalUnitType)-(Dimension)(obj)).GetValue(this.InternalUnitType)) 最后,我的最后一个想法是将我的单位类中的所有内容替换为基本单位
十进制
,而不是
双精度
(维度、角度等)替换为十进制,然后(在仔细研究之后)弄清楚这是否有帮助


如何以及在何处提高类的相等操作的精度一致性?


p、 s.库是开源的,可以找到(单位和几何体)

如果
e1
是第一行的方向,
e2
是第二行的方向,那么要检查它们是否在θ(弧度)的斜率公差内平行,请执行以下操作(伪代码):


bool is_parallel=| Cross(e1,e2)|您观察到的所有问题都是由于浮点运算造成的。通过实现众所周知的模式:XXXXX可以优雅地处理这些问题。请参见。如果您不需要那么高的精度,我建议不要使用小数。@jth41如果我有答案,我会提交一个答案,没有评论。:)我会让调用方决定所需的精度级别。在IsParallelTo和AreAllParallel方法中,包括一个公差参数,该参数给出了允许的最大角度。
//inside Dimension Equals
public override bool Equals(object obj)
{
    return (Math.Abs(this.Inches - ((Dimension)(obj)).Inches)) < Constants.AcceptedEqualityDeviationConstant;
}
bool is_parallel = |Cross(e1,e2)| <= |e1|*|e2|*Cos(θ)