1 #ifndef _PARANOIDNUMBER_H
2 #define _PARANOIDNUMBER_H
17 typedef enum {ADD, SUBTRACT, MULTIPLY, DIVIDE} Optype;
19 ParanoidNumber(float value=0, Optype type = ADD) : m_value(value), m_op(type), m_next_term(NULL), m_next_factor(NULL)
24 ParanoidNumber(const ParanoidNumber & cpy) : m_value(cpy.m_value), m_op(cpy.m_op), m_next_term(NULL), m_next_factor(NULL)
26 if (cpy.m_next_term != NULL)
28 m_next_term = new ParanoidNumber(*(cpy.m_next_term));
30 if (cpy.m_next_factor != NULL)
32 m_next_factor = new ParanoidNumber(*(cpy.m_next_factor));
36 ParanoidNumber(const ParanoidNumber & cpy, Optype type) : m_value(cpy.m_value), m_op(type), m_next_term(NULL), m_next_factor(NULL)
38 if (cpy.m_next_term != NULL)
40 m_next_term = new ParanoidNumber(*(cpy.m_next_term));
42 if (cpy.m_next_factor != NULL)
44 m_next_factor = new ParanoidNumber(*(cpy.m_next_factor));
48 ParanoidNumber(const char * str);
49 ParanoidNumber(const std::string & str) : ParanoidNumber(str.c_str()) {}
51 virtual ~ParanoidNumber()
53 if (m_next_term != NULL)
55 if (m_next_factor != NULL)
59 template <class T> T Convert() const;
60 double ToDouble() const {return Convert<double>();}
61 float ToFloat() const {return Convert<float>();}
63 bool Floating() const {return (m_next_term == NULL && m_next_factor == NULL);}
64 bool Sunken() const {return !Floating();} // I could not resist...
66 ParanoidNumber & operator+=(const ParanoidNumber & a);
67 ParanoidNumber & operator-=(const ParanoidNumber & a);
68 ParanoidNumber & operator*=(const ParanoidNumber & a);
69 ParanoidNumber & operator/=(const ParanoidNumber & a);
70 ParanoidNumber & operator=(const ParanoidNumber & a);
73 bool operator<(const ParanoidNumber & a) const {return ToDouble() < a.ToDouble();}
74 bool operator<=(const ParanoidNumber & a) const {return this->operator<(a) || this->operator==(a);}
75 bool operator>(const ParanoidNumber & a) const {return !(this->operator<=(a));}
76 bool operator>=(const ParanoidNumber & a) const {return !(this->operator<(a));}
77 bool operator==(const ParanoidNumber & a) const {return ToDouble() == a.ToDouble();}
78 bool operator!=(const ParanoidNumber & a) const {return !(this->operator==(a));}
80 ParanoidNumber operator+(const ParanoidNumber & a) const
82 ParanoidNumber result(*this);
86 ParanoidNumber operator-(const ParanoidNumber & a) const
88 ParanoidNumber result(*this);
92 ParanoidNumber operator*(const ParanoidNumber & a) const
94 ParanoidNumber result(*this);
98 ParanoidNumber operator/(const ParanoidNumber & a) const
100 ParanoidNumber result(*this);
105 std::string Str() const;
106 static char OpChar(Optype op)
108 static char opch[] = {'+','-','*','/'};
109 return opch[(int)op];
114 void SimplifyTerms();
115 void SimplifyFactors();
120 ParanoidNumber * m_next_term;
121 ParanoidNumber * m_next_factor;
132 T ParanoidNumber::Convert() const
134 T value = (m_op == SUBTRACT) ? -m_value : m_value;
135 const ParanoidNumber * n = m_next_factor;
141 value *= n->Convert<T>();
144 value /= n->Convert<T>();
147 Fatal("Shouldn't happen");
158 value += n->Convert<T>();
161 Fatal("Shouldn't happen");
170 #endif //_PARANOIDNUMBER_H