Comparing approximate values ​​in C # 4.0?

First of all, please excuse any typo, English is not my native language.

Here is my question. I am creating a class that represents approximate values ​​as such:

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

I want to use this class for undefined measurements, for example x = 8.31246 +/- 0.0045, and perform calculations on these values.

I want to overload the operators of this class. I don’t know how to implement the>,> =, <= and <operators ... The first thing I thought was something like this:

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

However, in the latter case, I am not satisfied with this "zero", since the exact result is not equal to "null". It may be "truth," or it may be a "lie."

Is there any object in .Net 4 that will help implement this function that I don’t know about, or am I doing the right way? I also thought about using an object instead of a logical one, which would determine in what circumstances the value is superior or not relative to another, instead of performing comparison operations, but I feel that it is too complicated for what I am trying to achieve ..

+4
source share
5 answers

This is one of the rare cases where it makes sense to define a value type (struct), which then fixes the null case problem. You can also change MinValue and MaxValue to calculate properties (just implement the get method, which evaluates the result), rather than store them when building.

On the other hand, comparing the approximate values ​​is itself an approximate operation, so you need to consider the use cases for your data type; Do you only intend to use comparison to determine when ranges do not overlap? It really depends on the value of your type. Is it intended to represent a data point from a normally distributed data set, where the uncertainty is a certain number of standard deviations for the sample? If so, it may make more sense for the comparison operation to return a numerical probability (which, of course, could not be called through the comparison operator).

+1
source

I would probably do something like this. I would execute IComparable<ApproximateValue> and then define <,>, <=, and> = according to the result of 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; } 
+3
source

It seems to me that you need to also check if a.MaxValue == b.MinValue in your current implementation that returns null , which seems wrong, it should either return true or false based on how you want the spec to actually work. I am not sure of any built-in .net functions for this, so I believe that you are doing the right way.

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

I would not bother with semantics > : I think bool? here is a dangerous type of return. However, given the uncertainty, you can return true if a more likely to be > b .

+1
source

It seems to me that you are trying to implement some form of Ternary Logic because you want the result of applying the operators to be either True, False, or Indefinite. The problem with this is that you really cannot combine inline logical values ​​with your undefined value. Therefore, although you can make a limited form of comparing two ApproximateValues , I think that it is not practical to use bool as a result of these comparisons, because it means that the result of comparisons can be freely combined with other expressions that lead to bool, but the possibility of an undefined value undermines this is. For example, it makes no sense to do the following when the result of the operation to the left of OR is undefined.

 ApproximateValue approx1 = ...; ApproximateValue approx2 = ...; bool result = ...; bool result = approx1 > approx2 || someBool; 

So, in my opinion, I do not think that it would be nice to implement comparisons as operators at all , if you want to preserve the uncertainty. The solutions proposed here eliminate uncertainty, which is fine, but not what was originally indicated.

+1
source

All Articles