Hello,
I am working on a program written by someone else and facing problems
in precisions due to usage of floating point date types. My input is
are the values in the rows of database (MS SQL Server) where fixed
point datatypes are used to store input as well as result e.g.
decimal(16,6) & money.
As the end I end up only using precision of 4 decimal instead of 6.
dblPrice =1.23333;
Amount = 91000000;
PricedAmount= dblPrice * Amount
PricedAmountshould have 112233030
But i am getting 112230300 (thus I am loosing precision).
dblPrice is declared as double
PricedAmount and Amount are objects of CCurrency
Here is the implementation of Multiplication operator of CCurrency
class and declaration of CCurrency
Any help to make this program more robust for more real implementation.
I have started to consider writign a class for fixed point arithmatic
datatype. Please let me know if it is a good start.
thanks and best wishes
abdul n. khan
---
class CCurrency
{
// Constructors
public:
CCurrency();
CCurrency(CURRENCY cySrc);
CCurrency(const CCurrency& curSrc);
CCurrency(const _variant_t & varSrc);
CCurrency(long nUnits, long nFractionalUnits);
CCurrency(__int64 int64Value);
// Attributes
public:
enum CCurrencyStatus
{
valid = 0,
invalid = 1, // Invalid currency (overflow, div 0,
etc.)
null = 2, // Literally has no value
};
CURRENCY m_cur;
CCurrencyStatus m_status;
void SetStatus(CCurrencyStatus status);
CCurrencyStatus GetStatus() const;
// Operations
public:
const CCurrency& operator=(CURRENCY cySrc);
const CCurrency& operator=(const CCurrency& curSrc);
const CCurrency& operator=(const _variant_t & varSrc);
BOOL operator==(const CCurrency& cur) const;
BOOL operator!=(const CCurrency& cur) const;
BOOL operator<(const CCurrency& cur) const;
BOOL operator>(const CCurrency& cur) const;
BOOL operator<=(const CCurrency& cur) const;
BOOL operator>=(const CCurrency& cur) const;
// CCurrency math
CCurrency operator+(const CCurrency& cur) const;
CCurrency operator-(const CCurrency& cur) const;
const CCurrency& operator+=(const CCurrency& cur);
const CCurrency& operator-=(const CCurrency& cur);
CCurrency operator-() const;
CCurrency operator*(const CCurrency& cur) const;
CCurrency operator*(long nOperand) const;
CCurrency operator*(float nOperand) const;
CCurrency operator*(double nOperand) const;
CCurrency operator/(long nOperand) const;
CCurrency operator/(float nOperand) const;
CCurrency operator/(double nOperand) const;
const CCurrency& operator*=(long nOperand);
const CCurrency& operator/=(long nOperand);
const CCurrency& operator*=(float nOperand);
const CCurrency& operator/=(float nOperand);
const CCurrency& operator*=(double nOperand);
const CCurrency& operator/=(double nOperand);
operator CURRENCY() const;
operator _variant_t() const;
// CCurrency definition
void SetCurrency(long nUnits, long nFractionalUnits);
CCurrency Absolute();
};
CCurrency CCurrency:

perator*(float nOperand) const
{
if (!GetStatus() == valid)
return *this;
CCurrency curOperand;
VarCyFromR4(nOperand,&curOperand.m_cur);
CCurrency curResult;
HRESULT hr = VarCyMul(*this, curOperand,&curResult.m_cur);
if FAILED(hr)
{
curResult.SetStatus(invalid);
curResult.m_cur.int64 = 0;
}
return curResult;
}
CCurrency CCurrency:

perator*(double nOperand) const
{
if (!GetStatus() == valid)
return *this;
CCurrency curOperand;
VarCyFromR8(nOperand,&curOperand.m_cur);
CCurrency curResult;
HRESULT hr = VarCyMul(*this, curOperand,&curResult.m_cur);
if FAILED(hr)
{
curResult.SetStatus(invalid);
curResult.m_cur.int64 = 0;
}
return curResult;
}