00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <math.h>
00018 #include <spl/Decimal.h>
00019 #include <spl/Double.h>
00020 #include <spl/String.h>
00021 #include <spl/text/StringBuffer.h>
00022 #include <stdio.h>
00023
00024 int const Decimal::precision = 4;
00025 int64 const Decimal::q = (int64)pow(10.0, (double)precision);
00026
00027 Decimal::Decimal(void)
00028 : n(0)
00029 {
00030 }
00031
00032 Decimal::Decimal(const Decimal& d)
00033 : n(d.n)
00034 {
00035 }
00036
00037 Decimal::Decimal(const int64 i)
00038 : n(i * q)
00039 {
00040 }
00041
00042 Decimal::Decimal(const int32 i)
00043 : n(i * q)
00044 {
00045 }
00046
00047 Decimal::Decimal(const int16 i)
00048 : n(i * q)
00049 {
00050 }
00051
00052 Decimal::Decimal(int64 intPart, int64 fractPart)
00053 : n(intPart * q + fractPart)
00054 {
00055 }
00056
00057 Decimal::Decimal(const double d)
00058 {
00059 double intPart;
00060 double fract = modf(d, &intPart);
00061 Init((int64)intPart, (int64)(fract*q));
00062 }
00063
00064 Decimal::Decimal(const float d)
00065 {
00066 float intPart;
00067 float fract = modff(d, &intPart);
00068 Init((int64)intPart, (int64)(fract*q));
00069 }
00070
00071 Decimal Decimal::Parse(const String& num)
00072 {
00073 return Decimal(Double::Parse(num));
00074 }
00075
00076 Decimal::~Decimal(void)
00077 {
00078 }
00079
00080 Decimal& Decimal::operator =(const Decimal& d)
00081 {
00082 n = d.n;
00083 return *this;
00084 }
00085
00086 Decimal& Decimal::operator =(const int32 d)
00087 {
00088 n=d;
00089 n*=q;
00090 return *this;
00091 }
00092
00093 Decimal& Decimal::operator =(const int64 d)
00094 {
00095 n=d;
00096 n*=q;
00097 return *this;
00098 }
00099
00100 Decimal& Decimal::operator =(const float d)
00101 {
00102 *this = Decimal(d);
00103 return *this;
00104 }
00105
00106 Decimal& Decimal::operator =(const double d)
00107 {
00108 double intPart;
00109 double fract = modf(d, &intPart);
00110 Init((int64)intPart, (int64)(fract*q));
00111 return *this;
00112 }
00113
00114 Decimal Decimal::operator +(const Decimal& d) const
00115 {
00116 return Decimal::Intern(n + d.n);
00117 }
00118
00119 Decimal Decimal::operator -(const Decimal& d) const
00120 {
00121 return Decimal::Intern(n - d.n);
00122 }
00123
00124 Decimal Decimal::operator *(const Decimal& d) const
00125 {
00126 return Decimal::Intern(n * d.n / q);
00127 }
00128
00129 Decimal Decimal::operator /(const Decimal& d) const
00130 {
00131 return Decimal::Intern(n * q / d.n);
00132 }
00133
00134 Decimal Decimal::operator +=(const Decimal& d)
00135 {
00136 n = n + d.n;
00137 return *this;
00138 }
00139
00140 Decimal Decimal::operator -=(const Decimal& d)
00141 {
00142 n = n - d.n;
00143 return *this;
00144 }
00145
00146 Decimal Decimal::operator *=(const Decimal& d)
00147 {
00148 n = n * d.n / q;
00149 return *this;
00150 }
00151
00152 Decimal Decimal::operator /=(const Decimal& d)
00153 {
00154 n = n * q / d.n;
00155 return *this;
00156 }
00157
00158 bool Decimal::operator ==(const Decimal& d) const
00159 {
00160 return n == d.n;
00161 }
00162
00163 bool Decimal::operator !=(const Decimal& d) const
00164 {
00165 return n != d.n;
00166 }
00167
00168 bool Decimal::operator <(const Decimal& d) const
00169 {
00170 return n < d.n;
00171 }
00172
00173 bool Decimal::operator <=(const Decimal& d) const
00174 {
00175 return n <= d.n;
00176 }
00177
00178 bool Decimal::operator >(const Decimal& d) const
00179 {
00180 return n > d.n;
00181 }
00182
00183 bool Decimal::operator >=(const Decimal& d) const
00184 {
00185 return n >= d.n;
00186 }
00187
00188 Decimal Decimal::Round()
00189 {
00190 int64 n2=n/q;
00191 int fract=(int)(n-n2*q);
00192 if ( fract > q/2 )
00193 {
00194 return Decimal(n2+1, 0);
00195 }
00196 return Decimal(n2, 0);
00197 }
00198
00199 int32 Decimal::HashCode() const
00200 {
00201 return (int32)((n & 0xFFFFFFFF) ^ (n >> 32));
00202 }
00203
00204 bool Decimal::Equals(Decimal *d) const
00205 {
00206 return n == d->n;
00207 }
00208
00209 bool Decimal::Equals(const IComparable *a) const
00210 {
00211 if (a->MajicNumber() != MajicNumber())
00212 {
00213 return false;
00214 }
00215 const Decimal *vp = static_cast<const Decimal *>(a);
00216 vp->ValidateMem();
00217 return Equals(vp);
00218 }
00219
00220 int Decimal::Compare(const IComparable *a) const
00221 {
00222 if (a->MajicNumber() != MajicNumber())
00223 {
00224 return 1;
00225 }
00226 const Decimal *vp = static_cast<const Decimal *>(a);
00227 vp->ValidateMem();
00228 return (int)(n - vp->n);
00229 }
00230
00231 bool Decimal::Equals(const IComparable& a) const
00232 {
00233 if (a.MajicNumber() != MajicNumber())
00234 {
00235 return false;
00236 }
00237 const Decimal& vp = static_cast<const Decimal&>(a);
00238 vp.ValidateMem();
00239 return Equals(vp);
00240 }
00241
00242 int Decimal::Compare(const IComparable& a) const
00243 {
00244 if (a.MajicNumber() != MajicNumber())
00245 {
00246 return 1;
00247 }
00248 const Decimal& vp = static_cast<const Decimal&>(a);
00249 vp.ValidateMem();
00250 return (int)(n - vp.n);
00251 }
00252
00253 int32 Decimal::MajicNumber() const
00254 {
00255 return DECIMAL_MAJIC;
00256 }
00257
00258 int Decimal::ToInt() const
00259 {
00260 return (int)ToLongInt();
00261 }
00262
00263 double Decimal::ToDouble() const
00264 {
00265 return Double::Parse(*ToString());
00266 }
00267
00268 StringPtr Decimal::ToString() const
00269 {
00270 char s[64];
00271 int64 n2=n / q;
00272 int fract = (int)(n-n2*q);
00273 sprintf(s, "%d.%0*d", (int)n2, precision, fract);
00274 return StringPtr(new String(s));
00275 }
00276
00277 #ifdef DEBUG
00278 void Decimal::ValidateMem() const
00279 {
00280 }
00281
00282 void Decimal::CheckMem() const
00283 {
00284 }
00285 #endif