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 сияқты пайдаланғым келеді және осы мәндер бойынша есептерді орындаңыз.

I want to overload operators in this class. I don't know how to implement the >, >=, <= and < operators... The first thing I thought of is 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; }
    }

Дегенмен, соңғы жағдайда, бұл нөлге қанағаттанбасам, дәл нәтиже «нөл» емес. Бұл «дұрыс» немесе «жалған» болуы мүмкін.

Бұл функцияны іске асыруға көмектесетін Нет 4-де қандай да бір объект бар ма, әлде мен дұрыс жолды білмеймін бе? Мен сондай-ақ, салыстыру операторларын іске асырудан гөрі құндылықтың артық немесе басқа емес екенін айқындайтын логиканың орнына объектіні пайдалану туралы ойланған едім, бірақ мен қол жеткізгім келетін нәрсе үшін біршама күрделі екенін сезінемін. .

4
@Jon, сіз дұрыссыз. Менің ойымша, ережені пайдалану жалғастырудың ең дәл жолы болады деп ойлаймын. Кейбір жағдайларда, мысалы, - 3.5 <4.3 және 3.7 <4.1 болса, кейбір жағдайларда a> b мәнін қайтару қажет болуы мүмкін, себебі кейбір жағдайларда бұл дұрыс және кейбір жағдайларда дұрыс емес, себебі ол әрдайым шын емес.
қосылды автор Guillaume, көзі
@JamesMichaelHare, жақсы кеңес, бұл туралы шын мәнінде білмедім.
қосылды автор Guillaume, көзі
@Ramhound, Мен алдаймын? өйткені нөлдік белгісіз мәнді іске асыру үшін көретін ең жақсы нәрсе болды.
қосылды автор Guillaume, көзі
Салыстыруды жүзеге асыра алмайсыз, өйткені салыстырудың жұмыс істеуі туралы нақты мәліметтер жоқ. Осындай салыстыруды басқаратын ережелерді жазып алыңыз. Егер сіз осындай ережелермен қиындықтарға тап болсаңыз, онда бұл контекстсіз салыстыру мағынасыз екенін білдіреді.
қосылды автор Jon, көзі
Неліктен логикалық операцияға қайтаруға тырысасыз? Мен ApproximateValue-ді нөлдік түрге айналдыруға мүмкіндік беретін себеп жоқ.
қосылды автор Security Hound, көзі
@Guillaume: FYI сияқты NET null> null жалған, null <�және> дегенді білдіреді.
қосылды автор James Michael Hare, көзі

5 жауаптар

I'd probably do something like this. I'd implement IComparable 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
қосылды
Бұл жақсы жауап, бірақ жалпы жағдайда бірдей болуы үшін екі құндылықты ескере отырып, дәл болмауы мүмкін.
қосылды автор Guillaume, көзі
return a.Value - a.Uncertainty > b.Value + b.Uncertainty

I wouldn't really mess with the semantics of >: I think bool? is a dangerous return type here. That said, given the uncertainty, you could return true, if a is more likely to be > b.

1
қосылды

a.MaxValue == b.MinValue , сіздің ағымдағы іске асыратын null кодын қайтаратындығын тексеру керек сияқты, бұл дұрыс емес сияқты, шын мәнінде жұмыс істейтіндіктен true немесе false қайтару. Осыған байланысты ешқандай кірістірілген функцияның жоқтығына сенімдімін, сондықтан дұрыс жолмен жүретініне сенемін.

1
қосылды

Бұл құндылық түрін (құрылымды) анықтау үшін маңыздырақ болатын сирек жағдайлардың бірі болып табылады, содан кейін нөлдік жағдайды жоймайды. Сондай-ақ, MinValue және MaxValue-ді есептік сипатта өзгертуге болады (құрылғыны сақтап қалудың орнына, нәтижені есептеу әдісі).

Бүйірлік нотада шамамен шамаланған мәндерді салыстыру өзі дерлік операция болып табылады, сондықтан сіз деректер түріне арналған пайдалану жағдайларын қарастыруыңыз керек; диапазондар бір-біріне қайшы келетінін анықтау үшін салыстыруды пайдаланғыңыз келе ме? Бұл сіздің түріңіздің мағынасына байланысты. Бұл қалыпты үлестірілетін деректер жиынтығынан деректер белгісін ұсынуға арналған ма, ол кезде белгісіздік таңдау үшін стандартты ауытқулардың кейбір саны болып табылады ма? Егер солай болса, салыстыру әрекеті үшін сандық ықтималдығын қайтаруға мағыналы болуы мүмкін (ол, әрине, салыстыру операторы арқылы шақырылуы мүмкін емес).

1
қосылды
Жақсы жауап, менің ойымша, мәселені ең жақсы жарықтандыратын және ең үлкен нүктелерді ескеру керек. Рахмет!
қосылды автор Guillaume, көзі

Менің ойымша, сіз өзіңіз қалағаныңыздай, сіз Ternary Logic -тің кейбір нысандарын орындауға тырысады деп ойлаймын операторлардың шын, жалған немесе анықталмаған қолданылу нәтижесі. Мәселе сіз кірістірілген логикалық мәндерді сіздің белгісіз мәніңізбен біріктіре алмайсыз. Сондықтан ApproximateValues ​​ екі кодын салыстырудың шектеулі түрін жасай алсаңыз да, бұл салыстырудың нәтижесі ретінде bool пайдалану дұрыс емес деп ойлаймын, себебі бұл салыстырудың нәтижесін білдіреді басқа өрнектермен еркін араласуға болады, алайда олар маңызы бар, бірақ анықталмаған құндылықтар бұл мүмкіндікті бұзады. Мысалы, сол жақта операцияның нәтижесі анықталмаған кезде төмендегілерді орындау мағынасы жоқ.

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

bool result = approx1 > approx2 || someBool; 

Сондықтан менің ойымша, егер салыстыруды операторлар ретінде қолдану болса, онда бұл белгісіздікті сақтағыңыз келеді деп ойламаймын. Мұнда ұсынылған шешімдер бастапқыда анықталмаған белгісіздікке жол бермейді.

1
қосылды
Басқа логикалық мәндермен салыстыру - бұл жақсы ...
қосылды автор Guillaume, көзі