64,686
社区成员
发帖
与我相关
我的任务
分享
/**
* @file WDouble.h
* @brief double型变量封装,可以设置精度
* @author 沙漠乌鸦
* @date 2009-09-07
* @warning WDouble类暂时需要实现的功能
* 1) 设置全局的默认精度和单独的精度
* 2) 返回原始double值或运用精度计算后的值
* 3) 同时支持正、负数的格式化
* 3) 大小比较符<、>、<=、>=
* 4) ==、!=操作符
* 5) +、-、*、/、+=、-=、*=、/=操作符
* 6) <<、>>操作符
*/
#pragma once
#include <iostream>
using std::ostream;
using std::istream;
namespace wuya
{
class WDouble
{
public:
WDouble(void);
WDouble(double dVal,size_t nPrecision = m_nPrecisionDef);
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& os,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
};
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& os,WDouble& object)
{
double dVal;
os >> dVal;
if(os)
{
object.m_dDblEnter = dVal;
object.Round();
}
else
object = WDouble();
return os;
}
};
#include "StdAfx.h"
#include "WDouble.h"
#include <math.h>
#include <boost/cast.hpp>
namespace wuya
{
size_t WDouble::m_nPrecisionDef = 1;
WDouble::WDouble(void): m_dDbl(0.0),m_dDblEnter(0.0),m_nPrecision(m_nPrecisionDef)
{
}
WDouble::WDouble(double dVal,size_t nPrecision /* = m_nPrecisionDef */) : m_dDblEnter(dVal),m_nPrecision(nPrecision)
{
Round();
}
WDouble::WDouble(const WDouble& dVal)
:m_dDbl(dVal.m_dDbl)
,m_dDblEnter(dVal.m_dDblEnter)
,m_nPrecision(dVal.m_nPrecision)
{
}
WDouble::~WDouble(void) throw()
{
}
WDouble& WDouble::operator = (const WDouble& dVal)
{
if(&dVal == this)
return *this;
this->m_dDbl = dVal.m_dDbl;
this->m_dDblEnter = dVal.m_dDblEnter;
this->m_nPrecision = dVal.m_nPrecision;
return *this;
}
WDouble& WDouble::operator = (double dVal)
{
this->m_dDblEnter = dVal;
this->m_nPrecision = m_nPrecisionDef;
Round();
return *this;
}
void WDouble::SetPrecisionDef(size_t nPrecision)
{
m_nPrecisionDef = nPrecision;
}
size_t WDouble::GetPrecisionDef()
{
return m_nPrecisionDef;
}
void WDouble::SetPrecision(size_t nPrecision)
{
this->m_nPrecision = nPrecision;
}
size_t WDouble::GetPrecision() const
{
return m_nPrecision;
}
double WDouble::Get() const
{
return m_dDbl;
}
double WDouble::Get(size_t nPrecision) const
{
return Round(nPrecision);
}
double WDouble::GetEnter() const
{
return m_dDblEnter;
}
double WDouble::Round(size_t nPrecision) const
{
using namespace boost;
double dPow = pow(10.0,(int)nPrecision);
double dResult,dVal;
if(m_dDblEnter >= 0)
dVal = (m_dDblEnter * dPow + 0.5);
else
dVal = (m_dDblEnter * dPow - 0.5);
try
{
__int64 lVal = numeric_cast<__int64>(dVal);
dResult = lVal / dPow;
}
catch(bad_numeric_cast&)
{
dResult = 0.0;
}
return dResult;
}
void WDouble::Round()
{
m_dDbl = Round(m_nPrecision);
}
}
#include "stdafx.h"
#include <iostream>
#include "WDouble.h"
using namespace wuya;
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
double d1 = 0.5514;
double d2 = 0.5416;
WDouble dVal1 = d1;
WDouble dVal2 = d2;
cout << dVal1.Get() << endl;
cout << dVal2.Get() << endl;
cout << dVal1.Get(3) << endl;
cout << dVal2.Get(3) << endl;
cout << dVal1 << dVal2 << endl;
int iPrecision = 2;
WDouble::SetPrecisionDef(iPrecision);
cout << "Precision Changed is" << iPrecision << endl;
dVal1 = d1;
dVal2 = d2;
cout << dVal1.Get() << endl;
cout << dVal2.Get() << endl;
cout << WDouble(1.7808,3).Get() << endl;
cout << WDouble(-1.54,1).Get() << endl;
cout << WDouble(-1.535,2).Get() << endl;
dVal1 += dVal2;
cout << dVal1.Get() << endl;
WDouble dVal10;
cin >> dVal10;
cout << dVal10 << endl;
system("pause");
return 0;
}