2016-10-23 24 views
-1

我一直在关注一些cpp练习来学习cpp,并且遇到了问题。我的课程中的相等运算符(==)不起作用

我创建了一个名为“FixedPoint2”的类来实现2位小数的定点数。我已经包含了包含以下所有功能的头文件。

我正在努力的是,当我试图测试出相等运算符时,我总是得到一个错误的答案。换句话说,发生以下情况:

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我认为他通过'operator double();'转换和比较双打,这可能会使[浮点数学被破坏?]的情况下得到(http://stackoverflow.com/questions/588004/是浮点数学),但我们也没有定义“FixedPoint”,所以我知道什么? – user4581301

回答

2

编译器不会自动生成operator==因为赔率是非常好的,它会弄错了很多往往比它得到它的权利。我们举一个简单的例子:一个动态字符串。编译器会生成比较字符的代码,对吗?它什么时候停止?现在编译器需要更多地了解程序员的意图和字符串,编译器不需要额外的心灵感应接口的复杂性。

更好地遵循一致的规则,不,并强制明确定义要比较什么是比较由人们假设他们得到他们想要的结果的废话代码的雷区。有关此主题的更长时间讨论:Why don't C++ compilers define operator== and operator!=?

编译器会寻找一种方法来满足比较。它没有找到直接的operator==,但它确实发现operator doubledouble s可用于比较。除了有时他们不能:Is floating point math broken?

这就是说我无法重现OP的结果。我期望完全相同的公式可以在完全相同的输入上得到完全相同的结果,即使结果是1.199999 ...而不是1.2

尽管我无法复制,但OP仍然更好地执行固定点operator==,因为没有固定点编号的不精确性。固定点将相等或不相等,不会是ifs ands或buts,所以“没有什么可以出错的!”另外,这个操作符应该是微不足道的。类似于return (rhs.m_digi == lhs.m_digi) && (rhs.m_deci == lhs.m_deci);