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(θ)