比较c#4.0中的近似值?

比较c#4.0中的近似值?,c#,C#,首先,请原谅任何打字错误,英语不是我的母语 这是我的问题。我正在创建一个表示近似值的类,例如: public sealed class ApproximateValue { public double MaxValue { get; private set; } public double MinValue { get; private set; } public double Uncertainty { get; private set; } public do

首先,请原谅任何打字错误,英语不是我的母语

这是我的问题。我正在创建一个表示近似值的类,例如:

public sealed class ApproximateValue
{
    public double MaxValue { get; private set; }
    public double MinValue { get; private set; }
    public double Uncertainty { get; private set; }
    public double Value { get; private set; }

    public ApproximateValue(double value, double uncertainty)
    {
        if (uncertainty < 0) { throw new ArgumentOutOfRangeException("uncertainty", "Value must be postivie or equal to 0."); }

        this.Value = value;
        this.Uncertainty = uncertainty;
        this.MaxValue = this.Value + this.Uncertainty;
        this.MinValue = this.Value - this.Uncertainty;
    }
}
公共密封类近似值
{
公共双MaxValue{get;private set;}
公共双最小值{get;私有集;}
公共双不确定性{get;私有集;}
公共双值{get;private set;}
公共近似值(双值,双不确定性)
{
如果(不确定性<0){抛出新的ArgumentOutOfRangeException(“不确定性”,“值必须是postivie或等于0”);}
这个。值=值;
不确定性=不确定性;
this.MaxValue=this.Value+this.definance;
this.MinValue=this.Value-this.definance;
}
}
我想将这个类用于不确定的测量,比如x=8.31246+/-0.0045,并对这些值进行计算

我想重载这个类中的运算符。我不知道如何实现>,>=,(近似值a,近似值b) { 如果(a==null | | b==null){返回null;} 如果(a.MinValue>b.MaxValue){return true;} else如果(a.MaxValue 然而,在最后一个例子中,我不满意这个“null”,因为准确的结果不是“null”。它可能是“真的”,也可能是“假的”


在.NET4中是否有任何对象可以帮助实现我不知道的这一功能,或者我的做法是否正确?我还考虑使用一个对象而不是一个布尔值来定义在什么情况下该值优于或不优于另一个,而不是实现比较运算符,但我觉得这对于我试图实现的目标来说有点太复杂了…

在我看来,您需要检查
a.MaxValue==b.MinValue
此外,在当前将返回
null
(这似乎不正确)的实现中,它应该根据您希望规范实际工作的方式返回
true
false
。我不确定是否有任何内置的.net功能用于此,因此我相信您正在以正确的方式进行操作。

这是一种罕见的情况,在这种情况下,定义一个值类型(struct)可能更有意义,从而消除空值大小写问题。您还可以将MinValue和MaxValue修改为计算属性(只需实现计算结果的get方法),而不必在构造时存储它们

在一个旁注中,近似值的比较本身是一个近似操作,因此需要考虑数据类型的用例;您是否仅打算使用比较来确定范围何时不重叠?这真的取决于你类型的含义。这是否表示正态分布数据集中的数据点,其中不确定度是抽样的一些标准偏差?如果是这样,比较操作返回数字概率(当然不能通过比较运算符调用)可能更有意义


我不会真正弄乱
>
的语义:我认为
bool?
在这里是一种危险的返回类型。也就是说,考虑到不确定性,您可以返回
true
,如果
a
更可能是
>b
,我可能会这样做。我将实现
IComparable
,然后根据
CompareTo()的结果定义,=:

public int CompareTo(近似值其他)
{
//如果other为null,则在.NET中默认情况下,我们的值更大,因此返回1。
如果(其他==null)
{
返回1;
}
//这是另一个
if(MinValue>other.MaxValue)
{
返回1;
}
//这是另一个
if(最大值<其他.MinValue)
{
返回-1;
}
//“相同”-ish
返回0;
}
公共静态布尔运算符(近似值左、近似值右)
{
return(right==null)?(left!=null):right.CompareTo(left)<0;
}

公共静态布尔运算符在我看来,您试图实现某种形式的,因为您希望应用运算符的结果为真、假或不确定。这样做的问题是,实际上无法将内置布尔值与不确定值组合。因此,虽然您可以对两个
近似值进行一些有限形式的比较
,但我认为使用
bool
作为这些比较的结果是不合适的,因为这意味着比较的结果可以与产生bool值的其他表达式自由组合,但不确定值的可能性削弱了这一点。例如,当OR左侧的操作结果不确定时,执行以下操作是没有意义的

ApproximateValue approx1 = ...;
ApproximateValue approx2 = ...;
bool result = ...;

bool result = approx1 > approx2 || someBool; 

因此,在我看来,如果你想保留不确定性,我认为将比较作为操作符来实现根本不是一个好主意。这里提供的解决方案消除了不确定性,这很好,但不是最初指定的不确定性。

您无法实现比较,因为您没有关于比较应该如何工作的规范。写下管理这种比较的规则。如果你很难想出这样的规则,那就是一个暗示,如果没有更多的上下文,比较是没有意义的。@Guillaume:正如供参考的那样,在.NET中null>null为false,null对于null的含义。为什么你要在布尔运算中返回null?我不是你允许ApproximateValue为可空类型的原因。@Jon,你是对的。我认为使用规则将是最准确的方法。在某些情况下,如果我有-例如-3.5b返回true
return a.Value - a.Uncertainty > b.Value + b.Uncertainty
public int CompareTo(ApproximateValue other)
{
    // if other is null, we are greater by default in .NET, so return 1.
    if (other == null)
    {
        return 1;
    }

    // this is > other
    if (MinValue > other.MaxValue)
    {
        return 1;
    }

    // this is < other
    if (MaxValue < other.MinValue)
    {
        return -1;
    }

    // "same"-ish
    return 0;
}

public static bool operator <(ApproximateValue left, ApproximateValue right)
{
    return (left == null) ? (right != null) : left.CompareTo(right) < 0;
}

public static bool operator >(ApproximateValue left, ApproximateValue right)
{
    return (right == null) ? (left != null) : right.CompareTo(left) < 0;
}

public static bool operator <=(ApproximateValue left, ApproximateValue right)
{
    return (left == null) || left.CompareTo(right) <= 0;
}

public static bool operator >=(ApproximateValue left, ApproximateValue right)
{
    return (right == null) || right.CompareTo(left) <= 0;
}

public static bool operator ==(ApproximateValue left, ApproximateValue right)
{
    return (left == null) ? (right == null) : left.CompareTo(right) == 0;
}

public static bool operator !=(ApproximateValue left, ApproximateValue right)
{
    return (left == null) ? (right != null) : left.CompareTo(left) != 0;
}
ApproximateValue approx1 = ...;
ApproximateValue approx2 = ...;
bool result = ...;

bool result = approx1 > approx2 || someBool;