2011-10-28 75 views
4

首先,請原諒任何錯字,英語不是我的母語。在c#4.0中比較近似值?

這是我的問題。我創建表示近似值爲這樣一類:

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; 
    } 
} 

我想使用這個類不確定觀測值,這些值如x = 8.31246 +/- 0.0045例如,進行計算。

我想重載此類中的操作符。我不知道如何實現的>,> =,< =和<運營商...我想的第一件事情是這樣的:

public static bool? operator >(ApproximateValue a, ApproximateValue b) 
    { 
     if (a == null || b == null) { return null; } 

     if (a.MinValue > b.MaxValue) { return true; } 
     else if (a.MaxValue < b.MinValue) { return false; } 
     else { return null; } 
    } 

然而,在後一種情況下,我由於準確的結果不是'空',所以不滿足於'空'。這可能是'真的',也可能是'假的'。

.net 4中是否有任何對象可以幫助實現這個功能,我不知道或者我正在做正確的方法?我也在考慮使用一個對象而不是布爾值來定義值在哪些情況下優於或不是另一個,而不是實現比較運算符,但是我覺得它對於我想實現的有點太複雜。 。

+3

您不能實現比較,因爲你不具備的比較應該如何工作的規範。寫下管理這種比較的規則。如果你很難提出這樣的規則,這暗示沒有更多的上下文,比較是沒有意義的。 – Jon

+3

@Guillaume:正如一個供參考,在.NET空> null是假的,空與空值的含義。 –

+0

你爲什麼試圖在布爾操作上返回null?我不是你甚至會允許近似值爲空的類型的原因。 –

回答

1

這是一個罕見的情況之一,它可能會更有意義定義值類型(結構),然後消除空情況下的關注。您還可以將MinValue和MaxValue修改爲計算屬性(僅實現計算結果的get方法),而不是在構建時存儲它們。

在附註中,近似值的比較本身就是一個近似的操作,所以您需要考慮數據類型的用例;你是否只打算使用比較來確定範圍何時不重疊?這真的取決於你的類型的含義。這是否意味着代表來自正態分佈數據集的數據點,其中不確定度是抽樣的一些標準偏差數?如果是的話,它可能會更有意義的比較操作返回一個數字的概率(這當然無法通過比較運算符來調用。)

+0

很好的回答,我覺得這是有問題的最好的覆蓋面和點的最大範圍內來考慮之一。謝謝! – Guillaume

1

它看起來像你對我需要檢查,如果a.MaxValue == b.MinValue此外,在當前的實施,將返回null,這似乎不正確,應該要麼基於要如何規範,以實際工作truefalse返回。我不確定任何內置的.net功能,所以我相信你會以正確的方式進行操作。

1
return a.Value - a.Uncertainty > b.Value + b.Uncertainty 

我不會真的惹語義>:我認爲bool?這裏是一個危險的返回類型。也就是說,考慮到不確定性,如果a更可能> b,您可以返回true

3

我可能會這樣做。我想實現IComparable<ApproximateValue>,然後定義<,>,< =和> =根據CompareTo()結果:

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; 
} 
+0

這是一個很好的答案,但考慮到兩個值是在一般情況下,同一個可能不夠不準確的,。 – Guillaume

1

在我看來,你想實現某種形式的Ternary Logic,因爲你想將運算符應用爲True,False或Indeterminate的結果。這樣做的問題是,你真的不能將內置的布爾值與你的不確定值結合起來。因此,雖然你可以做兩ApproximateValues一些比較有限的形式,我認爲這是不恰當的使用bool因爲這些比較的結果,因爲這意味着比較的結果可以導致布爾值的其他表現形式自由組合,但不確定的價值的可能性破壞了這一點。例如,當OR左邊的操作結果不確定時,執行以下操作是沒有意義的。

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

bool result = approx1 > approx2 || someBool; 

所以,在我看來,我不認爲這是如果要保留的不確定性,以實現在所有攀比作爲運營商是個好主意。這裏提供的解決方案消除了不確定性,這很好,但不是最初指定的。

+0

與其他布爾值比較是一個好點... – Guillaume