имхо класс можно покороче сделать и даже ввести таки преобразование в double/int (в этом случае надо запретить неявное преобразование в конструкторе - explicit). дружить операторы с классом не обязательно, все можно определить через базовые операции без доступа к структуре класса
Код | template <unsigned int precision> class SDouble { public: // construction SDouble (double=0); explicit SDouble (const SDouble&); // comparsion bool operator< (const SDouble&) const; bool operator== (const SDouble&) const; //unary operations SDouble operator-() const; // arithmetic updates SDouble& operator+= (const SDouble&); SDouble& operator-= (const SDouble&); SDouble& operator*= (const SDouble&); SDouble& operator/= (const SDouble&); // conversion operator double () const; };
template <unsigned int precision> bool operator!= (const SDouble<precision>& lhs, const SDouble<precision>& rhs) { return !(lhs == rhs); }
template <unsigned int precision> bool operator<= (const SDouble<precision>& lhs, const SDouble<precision>& rhs) { return lhs < rhs || lhs == rhs; }
template <unsigned int precision> bool operator>= (const SDouble<precision>& lhs, const SDouble<precision>& rhs) { return !(lhs < rhs) || lhs == rhs; }
template <unsigned int precision> bool operator> (const SDouble<precision>& lhs, const SDouble<precision>& rhs) { return !(lhs < rhs || lhs == rhs); }
#define DEF_BINOP(op,type,subtype) \ template <subtype S, typename T> \ type<S> operator op (const type<S> &lhs, const T &rhs) \ { \ return lhs op type<S>(rhs); \ } \ template <subtype S, typename T> \ type<S> operator op (const T &lhs, const type<S> &rhs) \ { \ return type<S>(lhs) op rhs; \ }
#define DEF_BINOP_EQ(op,type,subtype) \ template <subtype S> \ type<S> operator op (const type<S> &lhs, const type<S> &rhs) \ { \ type<S> result(lhs); \ result op= rhs; \ return result; \ } \ DEF_BINOP(op,type,subtype)
DEF_BINOP_EQ(+,SDouble,unsigned int) // SDouble operator + (conversable type, conversable type); DEF_BINOP_EQ(-,SDouble,unsigned int) // SDouble operator - (conversable type, conversable type); DEF_BINOP_EQ(*,SDouble,unsigned int) // SDouble operator * (conversable type, conversable type); DEF_BINOP_EQ(/,SDouble,unsigned int) // SDouble operator / (conversable type, conversable type);
DEF_BINOP(<,SDouble,unsigned int) DEF_BINOP(==,SDouble,unsigned int) DEF_BINOP(!=,SDouble,unsigned int) DEF_BINOP(<=,SDouble,unsigned int) DEF_BINOP(>=,SDouble,unsigned int) DEF_BINOP(>,SDouble,unsigned int)
int main() { SDouble<4> ssd0 = 7.12; SDouble<4> ssd (7.12); SDouble<4> (7.12) + SDouble<4> (5.0); SDouble<4> (7.12) + 5.0; 5.0 + SDouble<4> (7.12); SDouble<4> sdr = - ssd + 5.0;
SDouble<4> z = sdr + (5.0 - sdr) / ssd * 2;
sdr >= 5.0; 4 != ssd;
double x = sdr ; int y = int (sdr); }
|
а вообще велосипеды уже изобретены, можно готовым попользоваться:
Код | #include <boost/operators.hpp>
template <unsigned int precision> class SDouble : boost::operators<SDouble> { public: // construction SDouble (double=0); SDouble (const SDouble&); // comparsion bool operator< (const SDouble&) const; bool operator== (const SDouble&) const; // unary operations SDouble operator-() const; // arithmetic updates SDouble& operator+= (const SDouble&); SDouble& operator-= (const SDouble&); SDouble& operator*= (const SDouble&); SDouble& operator/= (const SDouble&); // conversion double get() const; };
int main() { SDouble<4> ssd (7.12); SDouble<4> (7.12) + SDouble<4> (5.0); SDouble<4> (7.12) + 5.0; 5.0 + SDouble<4> (7.12); SDouble<4> sdr = - ssd + 5.0;
SDouble<4> z = sdr + (5.0 - sdr) / ssd * 2;
sdr >= 5.0; 4 != ssd;
double x = sdr.get (); int y = int (sdr.get ()); }
|
|