Webmaster  |  Imprint 
C++ Server Pages
Main  |  License  |  Documentation  |  Download 

/home/tommi/tntdb/include/tntdb/decimal.h

00001 /*
00002  * Copyright (C) 2007,2012 Tommi Maekitalo, Mark Wright
00003  * 
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  * 
00009  * As a special exception, you may use this file as part of a free
00010  * software library without restriction. Specifically, if other files
00011  * instantiate templates or use macros or inline functions from this
00012  * file, or you compile this file and link it with other files to
00013  * produce an executable, this file does not by itself cause the
00014  * resulting executable to be covered by the GNU General Public
00015  * License. This exception does not however invalidate any other
00016  * reasons why the executable file might be covered by the GNU Library
00017  * General Public License.
00018  * 
00019  * This library is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00022  * Lesser General Public License for more details.
00023  * 
00024  * You should have received a copy of the GNU Lesser General Public
00025  * License along with this library; if not, write to the Free Software
00026  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00027  */
00028 
00029 #ifndef TNTDB_DECIMAL_H
00030 #define TNTDB_DECIMAL_H
00031 
00032 #include <string>
00033 #include <limits>
00034 #include <iosfwd>
00035 #include <tntdb/config.h>
00036 
00037 namespace tntdb
00038 {
00039   class Decimal
00040   {
00041     public:
00042 #ifdef HAVE_LONG_LONG
00043       typedef long long LongType;
00044 #else
00045       typedef long LongType;
00046 #endif
00047 #ifdef HAVE_UNSIGNED_LONG_LONG
00048       typedef unsigned long long UnsignedLongType;
00049 #else
00050       typedef unsigned long UnsignedLongType;
00051 #endif
00052     private:
00053 
00054       // inf: _mantissa is empty, _exponent = numeric_limits<short>::max()
00055       // nan: _mantissa is empty, _exponent==0
00056       std::string _mantissa;  // just '0'-'9'
00057       short _exponent;
00058       bool _negative;
00059 
00060       Decimal(const std::string& mantissa, short exponent, bool negative)
00061         : _mantissa(mantissa),
00062           _exponent(exponent),
00063           _negative(negative)
00064       { }
00065 
00066       friend class Parser;
00067 
00068       LongType _getInteger(LongType min, LongType max) const;
00069       UnsignedLongType _getUnsigned(UnsignedLongType max) const;
00070 
00071       template <typename IntType> IntType _getInteger() const
00072       { return _getInteger(std::numeric_limits<IntType>::min(),
00073                            std::numeric_limits<IntType>::max()); }
00074 
00075       template <typename UnsignedType> UnsignedType _getUnsigned() const
00076       { return _getUnsigned(std::numeric_limits<UnsignedLongType>::max()); }
00077 
00078       void _getInteger(short& ret) const                         { ret = _getInteger<short>(); }
00079       void _getInteger(int& ret) const                           { ret = _getInteger<int>(); }
00080       void _getInteger(long& ret) const                          { ret = _getInteger<long>(); }
00081 #ifdef HAVE_LONG_LONG
00082       void _getInteger(long long& ret) const                     { ret = _getInteger<long long>(); }
00083 #endif
00084       void _getInteger(unsigned short& ret) const                { ret = _getUnsigned<unsigned short>(); }
00085       void _getInteger(unsigned int& ret) const                  { ret = _getUnsigned<unsigned int>(); }
00086       void _getInteger(unsigned long& ret) const                 { ret = _getUnsigned<unsigned long>(); }
00087 #ifdef HAVE_UNSIGNED_LONG_LONG
00088       void _getInteger(unsigned long long& ret) const            { ret = _getUnsigned<unsigned long long>(); }
00089 #endif
00090 
00091       void _setInteger(LongType l, short exponent);
00092       void _setUnsigned(UnsignedLongType l, short exponent);
00093 
00094     public:
00095 
00096       class Parser;
00097 
00098       Decimal();
00099 
00100       explicit Decimal(long double value)
00101       { setDouble(value); }
00102 
00103       explicit Decimal(const std::string& value);
00104 
00105       explicit Decimal(long mantissa, short exponent)
00106       { setInteger(mantissa, exponent); }
00107 
00108       static Decimal infinity()
00109       { return Decimal(std::string(), std::numeric_limits<short>::max(), false); }
00110 
00111       static Decimal nan()
00112       { return Decimal(std::string(), 0, false); }
00113 
00114       const std::string& mantissa() const
00115       { return _mantissa; }
00116 
00117       short exponent() const
00118       { return _exponent; }
00119 
00120       bool negative() const
00121       { return _negative; }
00122 
00123       bool isInfinity(bool positiveInfinity = true) const
00124         { return _negative != positiveInfinity && _mantissa.empty() && _exponent == std::numeric_limits<short>::max(); }
00125 
00126       bool isPositiveInfinity() const
00127         { return isInfinity(true); }
00128 
00129       bool isNegativeInfinity() const
00130         { return isInfinity(false); }
00131 
00132       bool isNaN() const
00133         { return _mantissa.empty() && _exponent == 0; }
00134 
00135       bool isZero() const
00136         { return _mantissa == "0"; }
00137 
00138       void setDouble(long double value);
00139 
00140       long double getDouble() const;
00141 
00142       void setInteger(short l, short exponent = 0)               { _setInteger(l, exponent); }
00143       void setInteger(int l, short exponent = 0)                 { _setInteger(l, exponent); }
00144       void setInteger(long l, short exponent = 0)                { _setInteger(l, exponent); }
00145       void setInteger(long long l, short exponent = 0)           { _setInteger(l, exponent); }
00146       void setInteger(unsigned short l, short exponent = 0)      { _setUnsigned(l, exponent); }
00147       void setInteger(unsigned int l, short exponent = 0)        { _setUnsigned(l, exponent); }
00148       void setInteger(unsigned long l, short exponent = 0)       { _setUnsigned(l, exponent); }
00149       void setInteger(unsigned long long l, short exponent = 0)  { _setUnsigned(l, exponent); }
00150 
00151       template <typename IntType>
00152       IntType getInteger() const
00153       {
00154         IntType ret;
00155         _getInteger(ret);
00156         return ret;
00157       }
00158 
00159       std::string toString() const;
00160       std::string toStringSci() const;
00161       std::string toStringFix() const;
00162 
00163       Decimal operator- () const
00164         { return Decimal(_mantissa, _exponent, !_negative); }
00165 
00166       bool operator== (const Decimal& other) const
00167         { return !isNaN() && _mantissa == other._mantissa && _exponent == other._exponent && _negative == other._negative; }
00168 
00169       bool operator!= (const Decimal& other) const
00170       { return !(*this == other); }
00171 
00172       bool operator< (const Decimal& other) const;
00173 
00174       bool operator> (const Decimal& other) const
00175       { return other < *this; }
00176 
00177       bool operator<= (const Decimal& other) const
00178       { return !(other < *this); }
00179 
00180       bool operator>= (const Decimal& other) const
00181       { return !(other > *this); }
00182 
00183   };
00184 
00185   std::istream& operator>> (std::istream& in, Decimal& dec);
00186   std::ostream& operator<< (std::ostream& out, const Decimal& dec);
00187 
00188 }
00189 
00190 #endif // TNTDB_DECIMAL_H
00191 // vim:et:sw=2
Copyright © 2008 The Tntnet Development Team
Tntnet 1.6