00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
00055
00056 std::string _mantissa;
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