• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/Decimal.cpp

00001 /*
00002  *   This file is part of the Standard Portable Library (SPL).
00003  *
00004  *   SPL is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   SPL is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with SPL.  If not, see <http://www.gnu.org/licenses/>.
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