/** * @file WDouble.h * @brief double型变量封装,可以设置精度 * @author 沙漠乌鸦 * @date 2009-09-07 * @warning WDouble类暂时需要实现的功能 * 1) 设置全局的默认精度和单独的精度 * 2) 返回原始double值或运用精度计算后的值 * 3) 同时支持正、负数的格式化 * 3) 大小比较符<、>、<=、>= * 4) ==、!=操作符 * 5) +、-、*、/、+=、-=、*=、/=操作符 * 6) <<、>>操作符 */ #pragma once #include using std::ostream; using std::istream; namespace wuya { class AFX_EXT_CLASS WDouble { public: WDouble(void); WDouble(double dVal,size_t nPrecision = GetPrecisionDef()); WDouble(const WDouble& dVal); ~WDouble(void) throw(); WDouble& operator = (const WDouble& dVal); WDouble& operator = (double dVal); // operator friend inline bool operator == (const WDouble& dVal1,const WDouble& dVal2); friend inline bool operator != (const WDouble& dVal1,const WDouble& dVal2); friend inline bool operator < (const WDouble& dVal1,const WDouble& dVal2); friend inline bool operator > (const WDouble& dVal1,const WDouble& dVal2); friend inline bool operator <= (const WDouble& dVal1,const WDouble& dVal2); friend inline bool operator >= (const WDouble& dVal1,const WDouble& dVal2); friend inline void operator += (WDouble& dVal1,const WDouble& dVal2); ///< 精度以第一个操作数为准 friend inline void operator -= (WDouble& dVal1,const WDouble& dVal2); friend inline void operator *= (WDouble& dVal1,const WDouble& dVal2); friend inline void operator /= (WDouble& dVal1,const WDouble& dVal2); friend inline WDouble operator + (const WDouble& dVal1,const WDouble& dVal2); ///< 精度以精度较大的为准 friend inline WDouble operator - (const WDouble& dVal1,const WDouble& dVal2); friend inline WDouble operator * (const WDouble& dVal1,const WDouble& dVal2); friend inline WDouble operator / (const WDouble& dVal1,const WDouble& dVal2); friend inline ostream& operator << (ostream& os,const WDouble& object); friend inline istream& operator >> (istream& is,WDouble& object); /** * @brief 设置WDouble精度 * @param [in]nPrecision 由于double型精度最大支持10位,该值范围为0-10,若非该范围值,则保留原精度 */ void SetPrecision(size_t nPrecision); /** @brief 返回WDoule精度 */ size_t GetPrecision() const; /** * @brief 返回double值,精度为WDouble保存精度 */ double Get() const; /** * @brief 返回double值,精度为nPrecision */ double Get(size_t nPrecision) const; /** * @brief 返回输入的double值、未进行四舍五入 */ double GetEnter() const; static void SetPrecisionDef(size_t nPrecision); static size_t GetPrecisionDef(); private: /** @brief 对原始数据进行四舍五入计算 */ double Round(size_t nPrecision) const; void Round(); private: double m_dDbl; ///< 按照精度四舍五入后的double值 double m_dDblEnter; ///< 原始double值 size_t m_nPrecision; ///< double精度 static size_t m_nPrecisionDef; ///< 默认精度、值为1,即可以精确到0.1 }; //operator inline bool operator == (const WDouble& dVal1,const WDouble& dVal2) { return dVal1.m_dDbl == dVal2.m_dDbl; } inline bool operator != (const WDouble& dVal1,const WDouble& dVal2) { return dVal1.m_dDbl != dVal2.m_dDbl; } inline bool operator < (const WDouble& dVal1,const WDouble& dVal2) { return dVal1.m_dDbl < dVal2.m_dDbl; } inline bool operator > (const WDouble& dVal1,const WDouble& dVal2) { return dVal1.m_dDbl > dVal2.m_dDbl; } inline bool operator <= (const WDouble& dVal1,const WDouble& dVal2) { return dVal1.m_dDbl <= dVal2.m_dDbl; } inline bool operator >= (const WDouble& dVal1,const WDouble& dVal2) { return dVal1.m_dDbl >= dVal2.m_dDbl; } inline void operator += (WDouble& dVal1,const WDouble& dVal2) { dVal1.m_dDblEnter += dVal2.m_dDblEnter; // 以dVal1的精度为准 dVal1.Round(); } inline void operator -= (WDouble& dVal1,const WDouble& dVal2) { dVal1.m_dDblEnter -= dVal2.m_dDblEnter; // 以dVal1的精度为准 dVal1.Round(); } inline void operator *= (WDouble& dVal1,const WDouble& dVal2) { dVal1.m_dDblEnter *= dVal2.m_dDblEnter; // 以dVal1的精度为准 dVal1.Round(); } inline void operator /= (WDouble& dVal1,const WDouble& dVal2) { dVal1.m_dDblEnter /= dVal2.m_dDblEnter; // 以dVal1的精度为准 dVal1.Round(); dVal1.m_dDblEnter = dVal1.m_dDbl; } inline WDouble operator + (const WDouble& dVal1,const WDouble& dVal2) { size_t nPrecision; if(dVal1.m_nPrecision > dVal2.m_nPrecision) nPrecision = dVal1.m_nPrecision; else nPrecision = dVal2.m_nPrecision; WDouble dVal(dVal1.m_dDbl + dVal2.m_dDbl,nPrecision); return dVal; } inline WDouble operator - (const WDouble& dVal1,const WDouble& dVal2) { size_t nPrecision; if(dVal1.m_nPrecision > dVal2.m_nPrecision) nPrecision = dVal1.m_nPrecision; else nPrecision = dVal2.m_nPrecision; WDouble dVal(dVal1.m_dDbl - dVal2.m_dDbl,nPrecision); return dVal; } inline WDouble operator * (const WDouble& dVal1,const WDouble& dVal2) { size_t nPrecision; if(dVal1.m_nPrecision > dVal2.m_nPrecision) nPrecision = dVal1.m_nPrecision; else nPrecision = dVal2.m_nPrecision; WDouble dVal(dVal1.m_dDbl * dVal2.m_dDbl,nPrecision); return dVal; } inline WDouble operator / (const WDouble& dVal1,const WDouble& dVal2) { size_t nPrecision; if(dVal1.m_nPrecision > dVal2.m_nPrecision) nPrecision = dVal1.m_nPrecision; else nPrecision = dVal2.m_nPrecision; WDouble dVal(dVal1.m_dDbl / dVal2.m_dDbl,nPrecision); return dVal; } inline ostream& operator << (ostream& os,const WDouble& object) { os << object.m_dDbl; return os; } inline istream& operator >> (istream& is,WDouble& object) { double dVal; is >> dVal; if(is) { object.m_dDblEnter = dVal; object.Round(); } else object = WDouble(); return is; } };