2016-10-23 13 views
-1

私はcppの練習に従っています。問題を抱えています。私のクラスの等価演算子(==)が機能していません

固定小数点数を2小数点にするために「FixedPoint2」というクラスを作成しました。私は以下のすべての機能を含むヘッダーファイルを含めました。

私が苦労しているのは、私が等価演算子をテストしようとすると、私は常に偽の答えを得ることです。言い換えれば、次のようになります。

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 

あなたはそのアイデアを得ます。また、if文でテストして、オーバーロードされた呼び出しが問題ではないことを確認しました。たとえば:

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

私の直感は、何かが、私が見落としているいくつかの暗黙の型変換、または二重の内のいくつかの厄介なもののいずれかとしてアップしていると言われます。しかし、私はどちらかとは思わない。

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

このような問題を解決する正しいツールは、デバッガです。スタックオーバーフローを尋ねる前に、コードを一行ずつ進める必要があります。詳しいヘルプは、[小さなプログラムをデバッグする方法(Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)を参照してください。最低限、問題を再現する[最小、完全、および検証可能](http://stackoverflow.com/help/mcve)の例と、その問題を再現するためのデバッガ。 –

+4

'operator =='のオーバーロードはどこですか? – Charles

+4

@ c650私は彼が演算子double();に乗っていると思います。double型を変換して比較すると、浮動小数点数学が壊れていますか?(http://stackoverflow.com/questions/588004/) is-floating-point-math-broken)、私たちは 'FixedPoint'を定義していないので、何を知っていますか? – user4581301

答えて

2

オッズは、それは多くの、多くの場合、それはそれが正しい取得するよりも、それは間違って取得することは本当に良いですので、コンパイラが自動的にoperator==を生成しません。簡単な例を考えてみましょう:動的な文字列。コンパイラは、文字ごとに文字を比較するコードを生成するでしょうか?それはいつ終わるのですか?コンパイラは、プログラマの意図とその文字列の詳細を知る必要があり、コンパイラはテレパティックインタフェースの複雑さを余分に必要としません。

一貫性のあるルールで、比較するものを明示的に定義することは、人々が望むものを持っていると仮定した結果として得られるクラップコードの地雷欄よりも明白です。ここでのトピックについてのより長い議論:Why don't C++ compilers define operator== and operator!=?

コンパイラは比較を満たす方法を探します。直接operator==は見つかりませんが、operator doubledoubleが見つかりました。それ以外の場合は除きます:Is floating point math broken?

私はOPの結果を再現できないと言っています。正確な同じ結果を得るためには全く同じ結果を得るために全く同じ数式を実行することが期待されます。結果は1.199999 ... 1.2ではなく

私は再現できませんが、ポイントoperator==は固定小数点数の不正確さがないためです。固定小数点は等しいか等しくなく、ifs andsまたはbutsはありません。したがって、「何も間違ってはいけません!」さらに、この演算子は簡単に書くことができます。何かのようにreturn (rhs.m_digi == lhs.m_digi) && (rhs.m_deci == lhs.m_deci);

関連する問題