2016-10-23 3 views
-1

Ich habe einige CPP-Übungen zu lernen cpp und ich habe ein Problem festgestellt.Der Gleichheitsoperator (==) in meiner Klasse funktioniert nicht

Ich habe eine Klasse namens "FixedPoint2" erstellt, um eine Festkommazahl auf 2 Dezimalstellen zu implementieren. Ich habe die Header-Datei enthalten, die alle folgenden Funktionen enthält.

Womit ich mich bemühe ist, dass wenn ich versuche, den Gleichheitsoperator zu testen, ich immer eine falsche Antwort bekomme. Mit anderen Worten, Folgendes passiert:

cout << (FixedPoint2(1.0)==FixedPoint2(1.0)) << endl; //returns true as expected 
cout << (FixedPoint2(1.2)==FixedPoint2(1.2)) << endl; //returns false 
cout << FixedPoint2(1.2) << "\t" << FixedPoint2(1.2) << endl; returns 1.2 1.2 

So bekommen Sie die Idee. Ich habe es auch mit if-Anweisungen getestet, um sicherzustellen, dass mein überladener Call-Out nicht das Problem ist. Zum Beispiel:

if (FixedPoint2(4.5)==FixedPoint2(4.5)) 
    cout << "Don't post to stackoverflow"; //This doesn't print 

Meine Intuition sagt mir etwas im Busch ist mit entweder mit einem gewissen impliziter Typumwandlung ich übersehen haben, oder einige chaotisch Dingen innerhalb der doppelt. Aber ich glaube nicht, dass es so ist.

using namespace std; 


class FixedPoint2 
{ 
    private: 
     int16_t m_digi; //chosen because I want the range 
     int8_t m_deci; //chosen to optimise memory 
    public: 
     FixedPoint2(int16_t digi = 0, int8_t deci = 0):m_digi{digi}, m_deci{deci} 
     { 
      assert(!(deci>127 || deci<-127)); //to prevent overflows 
      if(deci<-100 || deci>100) //just in case some moron (me) does some weird decimal calculations 
      { 
       m_digi+=(static_cast<int16_t>(deci)/100); 
       m_deci+=(-100); 
      } 
     } 
    FixedPoint2(double mydouble) 
    { 
     if (mydouble>=0) //The if-else floors the absolute value of the integer base 
     { 
      m_digi=static_cast<int16_t>(floor(mydouble)); 
     } 
     else 
     { 
      m_digi=static_cast<int16_t>(floor(mydouble)+1); 
     } 
     m_deci=static_cast<int8_t>(round(100*(mydouble-m_digi))); //This rounds off the decimal to two digits 

    }; 

    operator double(); 

    friend ostream& operator<<(ostream &out, const FixedPoint2 &f1); 
    friend istream& operator>>(istream &in, FixedPoint2 &f1); 
    friend FixedPoint2 operator+(const FixedPoint2 &f1, const FixedPoint2 &f2); 
}; 

FixedPoint2::operator double() 
{ 
    double base= static_cast<double>(m_digi); 
    double decimal= static_cast<double>(m_deci); 
    return base+0.01*decimal; 
} 

ostream& operator<<(ostream &out, const FixedPoint2 &f1) 
{ 
    FixedPoint2 a=f1; 
    out << double(a); //this is an easy work around to handling the period placement for the fixed point number 
    return out; 
} 


istream& operator>>(istream &in, FixedPoint2 &f1) 
{ 
    double placeholder; 
    in>>placeholder; 
    f1=FixedPoint2(placeholder); 
    return in; 
} 

FixedPoint2 operator+(const FixedPoint2 &f1, const FixedPoint2 &f2) 
{ 
    return FixedPoint2(f1.m_digi+f2.m_digi, f1.m_deci+f2.m_deci); 
} 
+0

Das richtige Werkzeug, um solche Probleme zu lösen, ist Ihr Debugger. Sie sollten Schritt für Schritt durch Ihren Code * gehen, bevor Sie auf Stack Overflow nachfragen. Für weitere Hilfe lesen Sie bitte [Wie kleine Programme zu debuggen (von Eric Lippert)] (https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). Zumindest sollten Sie Ihre Frage bearbeiten, um ein [minimales, vollständiges und verifizierbares] (http://stackoverflow.com/help/mcve) Beispiel einzufügen, das Ihr Problem zusammen mit den Beobachtungen, die Sie in der Debugger. –

+4

Wo ist Ihre Überladung von 'operator =='? – Charles

+4

@ c650 Ich denke, er kommt mit dem 'operator double();' Konvertieren und Vergleichen von Doubles aus, was es zu einem Fall von [Ist Gleitkomma-Mathe gebrochen?] (Http://stackoverflow.com/questions/588004/ is-floating-point-math-broken), aber wir haben auch nicht 'FixedPoint' definiert, was weiß ich also? – user4581301

Antwort

2

Der Compiler nicht automatisch operator== erzeugen, weil die Quoten wirklich gut sind, dass sie es falsch viel öfter bekommen, als es es richtig macht. Nehmen wir ein einfaches Beispiel: eine dynamische Zeichenfolge. Der Compiler würde Code erzeugen, der Zeichen für Zeichen vergleicht, richtig? Wann hört es auf? Jetzt muss der Compiler mehr über die Absicht des Programmierers mit seiner Zeichenkette wissen, und der Compiler braucht nicht die zusätzliche Komplexität einer telepathischen Schnittstelle.

Besser auf konsistente Regel zu haben, nein, und erzwingen eine explizite Definition von dem, was verglichen werden soll als ein Minenfeld von Mist-Code aus Menschen, vorausgesetzt, sie haben bekommen, was sie wollten. Längere Diskussion über das Thema hier: Why don't C++ compilers define operator== and operator!=?

Der Compiler sucht nach einer Möglichkeit, den Vergleich zu erfüllen. Es findet keine direkte operator==, aber es findet operator double und double s kann für den Vergleich verwendet werden. Außer manchmal können sie nicht: Is floating point math broken?

Das sagte ich kann OP Ergebnisse nicht reproduzieren. Ich würde erwarten, dass die exakt gleiche Formel auf genau die gleiche Eingabe ausgeführt wird, um das exakt gleiche Ergebnis zu erhalten, auch wenn das Ergebnis 1,199999 ist ... statt 1,2

Während ich nicht reproduzieren kann, ist OP immer noch besser dran, das Fixed zu implementieren Punkt operator==, weil es keine Ungenauigkeit mit einer festen Punktnummer gibt. Fixpunkt ist gleich oder ungleich, kein Wenn unds oder Aber, "Nichts kann schiefgehen!" Außerdem sollte dieser Operator trivial zu schreiben sein. Etwas wie return (rhs.m_digi == lhs.m_digi) && (rhs.m_deci == lhs.m_deci);

Verwandte Themen