~fboranek/mariadb++/vs10

« back to all changes in this revision

Viewing changes to src/decimal.cpp

  • Committer: Frantisek Boranek
  • Date: 2015-01-16 17:43:53 UTC
  • Revision ID: fboranek@atlas.cz-20150116174353-bcozr7536mymemz4
- fixed hang in connection due not NULL paramet passed as local socket
- fixed memory leak in destruction of connection
- generating config file
- force to chose throwing exception during build 
- fixed compilatin by VS2010

error C2065: '__PRETTY_FUNCTION__' : undeclared identifier      src\statement.cpp       33
error C2872: 'time' : ambiguous symbol  src\statement.cpp       163
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int       D:\Workspace\git.mailserver.8.5.X\connect\extLibs\mariadb++\src\statement.cpp   163     1
error C2143: syntax error : missing ',' before '&'  src\statement.cpp       163
error C2511: 'void mariadb::statement::set_time(mariadb::u32,const int)' : overloaded member function not found in 'mariadb::statement' src\statement.cpp       164
error C3861: 'round': identifier not found      src\decimal.cpp 25
error C2668: 'pow' : ambiguous call to overloaded function      src\decimal.cpp 32
error C2466: cannot allocate an array of constant size 0        src\decimal.cpp 32
error C2065: '__func__' : undeclared identifier src\date_time.cpp       144


src\bind.cpp(49): warning C4800: 'const my_bool' : forcing value to bool 'true' or 'false' (performance warning)
src\connection.cpp(238): warning C4244: '+=' : conversion from 'my_ulonglong' to 'mariadb::u32', possible loss of data
src\connection.cpp(269): warning C4244: 'return' : conversion from 'my_ulonglong' to 'mariadb::u32', possible loss of data
src\date_time.cpp(65): warning C4996: 'localtime': This function or variable may be unsafe. Consider using localtime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
src\date_time.cpp(633): warning C4996: 'localtime': This function or variable may be unsafe. Consider using localtime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
src\date_time.cpp(647): warning C4996: 'gmtime': This function or variable may be unsafe. Consider using gmtime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
src\date_time.cpp(673): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
src\date_time.cpp(675): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
src\date_time.cpp(684): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
src\date_time.cpp(493): warning C4244: 'initializing' : conversion from 'mariadb::s64' to 'mariadb::u32', possible loss of data
src\date_time.cpp(496): warning C4244: 'initializing' : conversion from 'mariadb::s64' to 'mariadb::u32', possible loss of data
src\date_time.cpp(499): warning C4244: 'initializing' : conversion from 'mariadb::s64' to 'mariadb::u32', possible loss of data
src\date_time.cpp(502): warning C4244: 'initializing' : conversion from 'mariadb::s64' to 'mariadb::u32', possible loss of data
src\date_time.cpp(586): warning C4244: 'argument' : conversion from 'mariadb::u16' to 'mariadb::u8', possible loss of data
src\date_time.cpp(658): warning C4244: 'initializing' : conversion from 'mariadb::u16' to 'mariadb::u8', possible loss of data
src\date_time.cpp(659): warning C4244: 'initializing' : conversion from 'mariadb::u16' to 'mariadb::u8', possible loss of data
src\decimal.cpp(173): warning C4244: 'argument' : conversion from 'mariadb::s64' to 'mariadb::u8', possible loss of data
src\result_set.cpp(264): warning C4800: 'mariadb::u64' : forcing value to bool 'true' or 'false' (performance warning)
src\result_set.cpp(272): warning C4244: 'return' : conversion from 'mariadb::u64' to 'mariadb::u8', possible loss of data
src\result_set.cpp(280): warning C4244: 'return' : conversion from 'mariadb::s64' to 'mariadb::s8', possible loss of data
src\result_set.cpp(288): warning C4244: 'return' : conversion from 'mariadb::u64' to 'mariadb::u16', possible loss of data
src\result_set.cpp(296): warning C4244: 'return' : conversion from 'mariadb::s64' to 'mariadb::s16', possible loss of data
src\result_set.cpp(304): warning C4244: 'return' : conversion from 'mariadb::u64' to 'mariadb::u32', possible loss of data
src\result_set.cpp(312): warning C4244: 'return' : conversion from 'mariadb::s64' to 'mariadb::s32', possible loss of data
src\save_point.cpp(33): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
src\save_point.cpp(35): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
src\save_point.cpp(49): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
src\save_point.cpp(64): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
src\statement.cpp(85): warning C4244: 'return' : conversion from 'my_ulonglong' to 'mariadb::s32', possible loss of data
src\statement.cpp(96): warning C4244: 'return' : conversion from 'my_ulonglong' to 'mariadb::u32', possible loss of data
src\statement.cpp(125): warning C4244: 'argument' : conversion from 'mariadb::u64' to 'unsigned long', possible loss of data
src\time.cpp(55): warning C4996: 'localtime': This function or variable may be unsafe. Consider using localtime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
src\time.cpp(366): warning C4244: 'initializing' : conversion from 'mariadb::s64' to 'mariadb::u32', possible loss of data
src\time.cpp(369): warning C4244: 'initializing' : conversion from 'mariadb::s64' to 'mariadb::u32', possible loss of data
src\time.cpp(372): warning C4244: 'initializing' : conversion from 'mariadb::s64' to 'mariadb::u32', possible loss of data
src\time.cpp(375): warning C4244: 'argument' : conversion from 'mariadb::s64' to 'mariadb::u32', possible loss of data
src\time.cpp(419): warning C4996: 'localtime': This function or variable may be unsafe. Consider using localtime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
src\time.cpp(427): warning C4996: 'gmtime': This function or variable may be unsafe. Consider using gmtime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
src\time.cpp(438): warning C4244: 'initializing' : conversion from 'mariadb::u16' to 'mariadb::u8', possible loss of data
src\time.cpp(444): warning C4244: '=' : conversion from 'mariadb::u16' to 'mariadb::u8', possible loss of data
src\time.cpp(450): warning C4244: 'initializing' : conversion from 'double' to 'mariadb::u16', possible loss of data
src\time.cpp(460): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
src\time.cpp(462): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
//  M A R I A D B + +
3
 
//
4
 
//      Author   : Sylvain Rochette Langlois
5
 
//      License  : Boost Software License (http://www.boost.org/users/license.html)
6
 
//
7
 
 
8
 
#include <iomanip>
9
 
#include <sstream>
10
 
#include <limits>
11
 
#include <math.h>
12
 
#include <boost/lexical_cast.hpp>
13
 
#include <mariadb++/decimal.hpp>
14
 
 
15
 
using namespace mariadb;
16
 
 
17
 
namespace
18
 
{
19
 
        //
20
 
        // Result = (value1 * value2) / divider
21
 
        //
22
 
        s64 multiply_divide(s64 value1, s64 value2, s64 divider)
23
 
        {
24
 
                if ((abs(value1) <= std::numeric_limits<int>::max()) || (abs(value2) <= std::numeric_limits<int>::max()))
25
 
                        return round(static_cast<f64>(value1 * value2) / static_cast<f64>(divider));
26
 
 
27
 
                return round(static_cast<f64>(value1) * static_cast<f64>(value2) / static_cast<f64>(divider));
28
 
        }
29
 
}
30
 
 
31
 
const s64 decimal::g_factors[] = {
32
 
        static_cast<s64>(pow(10, 0)),
33
 
        static_cast<s64>(pow(10, 1)),
34
 
        static_cast<s64>(pow(10, 2)),
35
 
        static_cast<s64>(pow(10, 3)),
36
 
        static_cast<s64>(pow(10, 4)),
37
 
        static_cast<s64>(pow(10, 5)),
38
 
        static_cast<s64>(pow(10, 6)),
39
 
        static_cast<s64>(pow(10, 7)),
40
 
        static_cast<s64>(pow(10, 8)),
41
 
        static_cast<s64>(pow(10, 9)),
42
 
        static_cast<s64>(pow(10, 10)),
43
 
        static_cast<s64>(pow(10, 11)),
44
 
        static_cast<s64>(pow(10, 12)),
45
 
        static_cast<s64>(pow(10, 13)),
46
 
        static_cast<s64>(pow(10, 14)),
47
 
        static_cast<s64>(pow(10, 15)),
48
 
        static_cast<s64>(pow(10, 16)),
49
 
        static_cast<s64>(pow(10, 17)),
50
 
        static_cast<s64>(pow(10, 18)),
51
 
        static_cast<s64>(pow(10, 19)),
52
 
        static_cast<s64>(pow(10, 20)),
53
 
        static_cast<s64>(pow(10, 21)),
54
 
        static_cast<s64>(pow(10, 22)),
55
 
        static_cast<s64>(pow(10, 23)),
56
 
        static_cast<s64>(pow(10, 24)),
57
 
        static_cast<s64>(pow(10, 25)),
58
 
        static_cast<s64>(pow(10, 26)),
59
 
        static_cast<s64>(pow(10, 27)),
60
 
        static_cast<s64>(pow(10, 28)),
61
 
        static_cast<s64>(pow(10, 29)),
62
 
        static_cast<s64>(pow(10, 30)),
63
 
        static_cast<s64>(pow(10, 31)),
64
 
        static_cast<s64>(pow(10, 32)),
65
 
        static_cast<s64>(pow(10, 33)),
66
 
        static_cast<s64>(pow(10, 34)),
67
 
        static_cast<s64>(pow(10, 35)),
68
 
        static_cast<s64>(pow(10, 36)),
69
 
        static_cast<s64>(pow(10, 37)),
70
 
        static_cast<s64>(pow(10, 38)),
71
 
        static_cast<s64>(pow(10, 39)),
72
 
        static_cast<s64>(pow(10, 40)),
73
 
        static_cast<s64>(pow(10, 41)),
74
 
        static_cast<s64>(pow(10, 42)),
75
 
        static_cast<s64>(pow(10, 43)),
76
 
        static_cast<s64>(pow(10, 44)),
77
 
        static_cast<s64>(pow(10, 45)),
78
 
        static_cast<s64>(pow(10, 46)),
79
 
        static_cast<s64>(pow(10, 47)),
80
 
        static_cast<s64>(pow(10, 48)),
81
 
        static_cast<s64>(pow(10, 49)),
82
 
        static_cast<s64>(pow(10, 40)),
83
 
        static_cast<s64>(pow(10, 51)),
84
 
        static_cast<s64>(pow(10, 52)),
85
 
        static_cast<s64>(pow(10, 53)),
86
 
        static_cast<s64>(pow(10, 54)),
87
 
        static_cast<s64>(pow(10, 55)),
88
 
        static_cast<s64>(pow(10, 56)),
89
 
        static_cast<s64>(pow(10, 57)),
90
 
        static_cast<s64>(pow(10, 58)),
91
 
        static_cast<s64>(pow(10, 59)),
92
 
        static_cast<s64>(pow(10, 60)),
93
 
        static_cast<s64>(pow(10, 61)),
94
 
        static_cast<s64>(pow(10, 62)),
95
 
        static_cast<s64>(pow(10, 63)),
96
 
};
97
 
 
98
 
//
99
 
// Constructors
100
 
//
101
 
decimal::decimal() :
102
 
        m_precision(4),
103
 
        m_value(0)
104
 
{
105
 
}
106
 
 
107
 
decimal::decimal(const decimal& src) :
108
 
        m_precision(src.m_precision),
109
 
        m_value(src.m_value)
110
 
{
111
 
}
112
 
 
113
 
decimal::decimal(const char* string) :
114
 
        m_precision(0),
115
 
        m_value(0)
116
 
{
117
 
        //
118
 
        // Extract the amount of precision required
119
 
        //
120
 
        std::string str = string;
121
 
        size_t pos = str.find(".");
122
 
 
123
 
        if (pos >= 0)
124
 
        {
125
 
                m_precision = str.length() - pos - 1;
126
 
                m_value = boost::lexical_cast<s64>(str.substr(0, pos)) * g_factors[m_precision] + boost::lexical_cast<s64>(str.substr(pos + 1));
127
 
        }
128
 
        else
129
 
                m_value = boost::lexical_cast<s64>(string);
130
 
}
131
 
 
132
 
//
133
 
// Methods
134
 
//
135
 
s64 decimal::factor() const
136
 
{
137
 
        return g_factors[m_precision];
138
 
}
139
 
 
140
 
u8 decimal::precision() const
141
 
{
142
 
        return m_precision;
143
 
}
144
 
 
145
 
//
146
 
// Convert a decimal to the same precision as this one
147
 
//
148
 
s64 decimal::convert(const decimal& dec) const
149
 
{
150
 
        if (m_precision == dec.m_precision)
151
 
                return dec.m_value;
152
 
 
153
 
        return (dec.m_value / dec.factor()) * factor();
154
 
}
155
 
 
156
 
decimal decimal::abs() const
157
 
{
158
 
        if (m_value >= 0)
159
 
                return *this;
160
 
 
161
 
        return decimal(0, factor()) - *this;
162
 
}
163
 
 
164
 
//
165
 
// Operators
166
 
//
167
 
int decimal::compare(const decimal& dec) const
168
 
{
169
 
        const s64 b = convert(dec);
170
 
 
171
 
        if (m_value < b)
172
 
                return -1;
173
 
 
174
 
        if (m_value > b)
175
 
                return 1;
176
 
 
177
 
        return 0;
178
 
}
179
 
 
180
 
//
181
 
// String
182
 
//
183
 
std::string decimal::str() const
184
 
{
185
 
        s64 after = m_value % factor();
186
 
        s64 before = (m_value - after) / factor();
187
 
 
188
 
        std::ostringstream out;
189
 
        out << before << '.' << std::setw(m_precision) << std::setfill('0') << std::right << after;
190
 
        return out.str();
191
 
}
192
 
 
193
 
//
194
 
// Get decimal
195
 
//
196
 
f32 decimal::float32() const
197
 
{
198
 
        return static_cast<f32>(m_value) / static_cast<f32>(m_precision * factor());
199
 
}
200
 
 
201
 
f64 decimal::double64() const
202
 
{
203
 
        return static_cast<f64>(m_value) / static_cast<f64>(m_precision * factor());
204
 
}
205
 
 
206
 
f128 decimal::double128() const
207
 
{
208
 
        return static_cast<f128>(m_value) / static_cast<f128>(m_precision * factor());
209
 
}
210
 
 
211
 
//
212
 
// Returns interget value = real_value * (10 ^ precision)
213
 
//
214
 
s64 decimal::unbiased() const
215
 
{
216
 
        return m_value;
217
 
}
218
 
 
219
 
//
220
 
// Operators
221
 
//
222
 
decimal& decimal::operator = (const decimal& dec)
223
 
{
224
 
        if (&dec != this)
225
 
                m_value = convert(dec);
226
 
 
227
 
        return *this;
228
 
}
229
 
 
230
 
decimal& decimal::operator = (s64 dec)
231
 
{
232
 
        m_value = factor() * dec;
233
 
        return *this;
234
 
}
235
 
 
236
 
decimal& decimal::operator = (s32 dec)
237
 
{
238
 
        m_value = factor() * dec;
239
 
        return *this;
240
 
}
241
 
 
242
 
decimal& decimal::operator = (f64 dec)
243
 
{
244
 
        m_value = round(static_cast<f64>(factor()) * dec);
245
 
        return *this;
246
 
}
247
 
 
248
 
decimal& decimal::operator = (f32 dec)
249
 
{
250
 
        m_value = round(static_cast<f64>(factor()) * dec);
251
 
        return *this;
252
 
}
253
 
 
254
 
bool decimal::operator == (const decimal& dec) const
255
 
{
256
 
        return m_value == convert(dec);
257
 
}
258
 
 
259
 
bool decimal::operator < (const decimal& dec) const
260
 
{
261
 
        return m_value < convert(dec);
262
 
}
263
 
 
264
 
bool decimal::operator <= (const decimal& dec) const
265
 
{
266
 
        return m_value <= convert(dec);
267
 
}
268
 
 
269
 
bool decimal::operator > (const decimal& dec) const
270
 
{
271
 
        return m_value > convert(dec);
272
 
}
273
 
 
274
 
bool decimal::operator >= (const decimal& dec) const
275
 
{
276
 
        return m_value >= convert(dec);
277
 
}
278
 
 
279
 
bool decimal::operator != (const decimal& dec) const
280
 
{
281
 
        return !(*this == dec);
282
 
}
283
 
 
284
 
const decimal decimal::operator + (const decimal& dec) const
285
 
{
286
 
        decimal result = *this;
287
 
        result.m_value += convert(dec);
288
 
        return result;
289
 
}
290
 
 
291
 
decimal& decimal::operator += (const decimal& dec)
292
 
{
293
 
        m_value += convert(dec);
294
 
        return *this;
295
 
}
296
 
 
297
 
const decimal decimal::operator - (const decimal& dec) const
298
 
{
299
 
        decimal result = *this;
300
 
        result.m_value -= convert(dec);
301
 
        return result;
302
 
}
303
 
 
304
 
decimal& decimal::operator -= (const decimal& dec)
305
 
{
306
 
        m_value -= convert(dec);
307
 
        return *this;
308
 
}
309
 
 
310
 
const decimal decimal::operator * (const decimal& dec) const
311
 
{
312
 
        decimal result = *this;
313
 
        multiply_divide(result.m_value, convert(dec), factor());
314
 
        return result;
315
 
}
316
 
 
317
 
decimal& decimal::operator *= (const decimal& dec)
318
 
{
319
 
        m_value = multiply_divide(m_value, convert(dec), factor());
320
 
        return *this;
321
 
}
322
 
 
323
 
const decimal decimal::operator / (const decimal& dec) const
324
 
{
325
 
        decimal result = *this;
326
 
        result.m_value = multiply_divide(result.m_value, factor(), convert(dec));
327
 
        return result;
328
 
}
329
 
 
330
 
decimal& decimal::operator /= (const decimal& dec)
331
 
{
332
 
        m_value = multiply_divide(m_value, factor(), convert(dec));
333
 
        return *this;
334
 
}
 
1
//
 
2
//  M A R I A D B + +
 
3
//
 
4
//      Author   : Sylvain Rochette Langlois
 
5
//      License  : Boost Software License (http://www.boost.org/users/license.html)
 
6
//
 
7
 
 
8
#include <iomanip>
 
9
#include <sstream>
 
10
#include <limits>
 
11
#include <math.h>
 
12
#include <boost/lexical_cast.hpp>
 
13
#include <mariadb++/decimal.hpp>
 
14
 
 
15
 
 
16
#ifdef MARIADB_WITHOUT_CPP11
 
17
namespace
 
18
{
 
19
        template <typename type>
 
20
        mariadb::s64 round(type value)
 
21
        {
 
22
                return mariadb::s64(value < 0.0 ? value - 0.5 : value + 0.5);
 
23
        }
 
24
}
 
25
#endif
 
26
 
 
27
using namespace mariadb;
 
28
 
 
29
namespace
 
30
{
 
31
        //
 
32
        // Result = (value1 * value2) / divider
 
33
        //
 
34
        s64 multiply_divide(s64 value1, s64 value2, s64 divider)
 
35
        {
 
36
                if ((abs(value1) <= std::numeric_limits<int>::max()) || (abs(value2) <= std::numeric_limits<int>::max()))
 
37
                        return round(static_cast<f64>(value1 * value2) / static_cast<f64>(divider));
 
38
 
 
39
                return round(static_cast<f64>(value1)* static_cast<f64>(value2) / static_cast<f64>(divider));
 
40
        }
 
41
}
 
42
 
 
43
const s64 decimal::g_factors[] = {
 
44
        static_cast<s64>(pow(.10, .0)),
 
45
        static_cast<s64>(pow(.10, .1)),
 
46
        static_cast<s64>(pow(.10, .2)),
 
47
        static_cast<s64>(pow(.10, .3)),
 
48
        static_cast<s64>(pow(.10, .4)),
 
49
        static_cast<s64>(pow(.10, .5)),
 
50
        static_cast<s64>(pow(.10, .6)),
 
51
        static_cast<s64>(pow(.10, .7)),
 
52
        static_cast<s64>(pow(.10, .8)),
 
53
        static_cast<s64>(pow(.10, .9)),
 
54
        static_cast<s64>(pow(.10, .10)),
 
55
        static_cast<s64>(pow(.10, .11)),
 
56
        static_cast<s64>(pow(.10, .12)),
 
57
        static_cast<s64>(pow(.10, .13)),
 
58
        static_cast<s64>(pow(.10, .14)),
 
59
        static_cast<s64>(pow(.10, .15)),
 
60
        static_cast<s64>(pow(.10, .16)),
 
61
        static_cast<s64>(pow(.10, .17)),
 
62
        static_cast<s64>(pow(.10, .18)),
 
63
        static_cast<s64>(pow(.10, .19)),
 
64
        static_cast<s64>(pow(.10, .20)),
 
65
        static_cast<s64>(pow(.10, .21)),
 
66
        static_cast<s64>(pow(.10, .22)),
 
67
        static_cast<s64>(pow(.10, .23)),
 
68
        static_cast<s64>(pow(.10, .24)),
 
69
        static_cast<s64>(pow(.10, .25)),
 
70
        static_cast<s64>(pow(.10, .26)),
 
71
        static_cast<s64>(pow(.10, .27)),
 
72
        static_cast<s64>(pow(.10, .28)),
 
73
        static_cast<s64>(pow(.10, .29)),
 
74
        static_cast<s64>(pow(.10, .30)),
 
75
        static_cast<s64>(pow(.10, .31)),
 
76
        static_cast<s64>(pow(.10, .32)),
 
77
        static_cast<s64>(pow(.10, .33)),
 
78
        static_cast<s64>(pow(.10, .34)),
 
79
        static_cast<s64>(pow(.10, .35)),
 
80
        static_cast<s64>(pow(.10, .36)),
 
81
        static_cast<s64>(pow(.10, .37)),
 
82
        static_cast<s64>(pow(.10, .38)),
 
83
        static_cast<s64>(pow(.10, .39)),
 
84
        static_cast<s64>(pow(.10, .40)),
 
85
        static_cast<s64>(pow(.10, .41)),
 
86
        static_cast<s64>(pow(.10, .42)),
 
87
        static_cast<s64>(pow(.10, .43)),
 
88
        static_cast<s64>(pow(.10, .44)),
 
89
        static_cast<s64>(pow(.10, .45)),
 
90
        static_cast<s64>(pow(.10, .46)),
 
91
        static_cast<s64>(pow(.10, .47)),
 
92
        static_cast<s64>(pow(.10, .48)),
 
93
        static_cast<s64>(pow(.10, .49)),
 
94
        static_cast<s64>(pow(.10, .40)),
 
95
        static_cast<s64>(pow(.10, .51)),
 
96
        static_cast<s64>(pow(.10, .52)),
 
97
        static_cast<s64>(pow(.10, .53)),
 
98
        static_cast<s64>(pow(.10, .54)),
 
99
        static_cast<s64>(pow(.10, .55)),
 
100
        static_cast<s64>(pow(.10, .56)),
 
101
        static_cast<s64>(pow(.10, .57)),
 
102
        static_cast<s64>(pow(.10, .58)),
 
103
        static_cast<s64>(pow(.10, .59)),
 
104
        static_cast<s64>(pow(.10, .60)),
 
105
        static_cast<s64>(pow(.10, .61)),
 
106
        static_cast<s64>(pow(.10, .62)),
 
107
        static_cast<s64>(pow(.10, .63)),
 
108
};
 
109
 
 
110
//
 
111
// Constructors
 
112
//
 
113
decimal::decimal() :
 
114
        m_precision(4),
 
115
        m_value(0)
 
116
{
 
117
}
 
118
 
 
119
decimal::decimal(const decimal& src) :
 
120
        m_precision(src.m_precision),
 
121
        m_value(src.m_value)
 
122
{
 
123
}
 
124
 
 
125
decimal::decimal(const char* string) :
 
126
        m_precision(0),
 
127
        m_value(0)
 
128
{
 
129
        //
 
130
        // Extract the amount of precision required
 
131
        //
 
132
        std::string str = string;
 
133
        size_t pos = str.find(".");
 
134
 
 
135
        if (pos >= 0)
 
136
        {
 
137
                m_precision = boost::lexical_cast<u8>(str.length() - pos - 1);
 
138
                m_value = boost::lexical_cast<s64>(str.substr(0, pos)) * g_factors[m_precision] + boost::lexical_cast<s64>(str.substr(pos + 1));
 
139
        }
 
140
        else
 
141
                m_value = boost::lexical_cast<s64>(string);
 
142
}
 
143
 
 
144
//
 
145
// Methods
 
146
//
 
147
s64 decimal::factor() const
 
148
{
 
149
        return g_factors[m_precision];
 
150
}
 
151
 
 
152
u8 decimal::precision() const
 
153
{
 
154
        return m_precision;
 
155
}
 
156
 
 
157
//
 
158
// Convert a decimal to the same precision as this one
 
159
//
 
160
s64 decimal::convert(const decimal& dec) const
 
161
{
 
162
        if (m_precision == dec.m_precision)
 
163
                return dec.m_value;
 
164
 
 
165
        return (dec.m_value / dec.factor()) * factor();
 
166
}
 
167
 
 
168
decimal decimal::abs() const
 
169
{
 
170
        if (m_value >= 0)
 
171
                return *this;
 
172
 
 
173
        return decimal(0, static_cast<u8>(factor())) - *this;
 
174
}
 
175
 
 
176
//
 
177
// Operators
 
178
//
 
179
int decimal::compare(const decimal& dec) const
 
180
{
 
181
        const s64 b = convert(dec);
 
182
 
 
183
        if (m_value < b)
 
184
                return -1;
 
185
 
 
186
        if (m_value > b)
 
187
                return 1;
 
188
 
 
189
        return 0;
 
190
}
 
191
 
 
192
//
 
193
// String
 
194
//
 
195
std::string decimal::str() const
 
196
{
 
197
        s64 after = m_value % factor();
 
198
        s64 before = (m_value - after) / factor();
 
199
 
 
200
        std::ostringstream out;
 
201
        out << before << '.' << std::setw(m_precision) << std::setfill('0') << std::right << after;
 
202
        return out.str();
 
203
}
 
204
 
 
205
//
 
206
// Get decimal
 
207
//
 
208
f32 decimal::float32() const
 
209
{
 
210
        return static_cast<f32>(m_value) / static_cast<f32>(m_precision * factor());
 
211
}
 
212
 
 
213
f64 decimal::double64() const
 
214
{
 
215
        return static_cast<f64>(m_value) / static_cast<f64>(m_precision * factor());
 
216
}
 
217
 
 
218
f128 decimal::double128() const
 
219
{
 
220
        return static_cast<f128>(m_value) / static_cast<f128>(m_precision * factor());
 
221
}
 
222
 
 
223
//
 
224
// Returns interget value = real_value * (10 ^ precision)
 
225
//
 
226
s64 decimal::unbiased() const
 
227
{
 
228
        return m_value;
 
229
}
 
230
 
 
231
//
 
232
// Operators
 
233
//
 
234
decimal& decimal::operator = (const decimal& dec)
 
235
{
 
236
        if (&dec != this)
 
237
                m_value = convert(dec);
 
238
 
 
239
        return *this;
 
240
}
 
241
 
 
242
decimal& decimal::operator = (s64 dec)
 
243
{
 
244
        m_value = factor() * dec;
 
245
        return *this;
 
246
}
 
247
 
 
248
decimal& decimal::operator = (s32 dec)
 
249
{
 
250
        m_value = factor() * dec;
 
251
        return *this;
 
252
}
 
253
 
 
254
decimal& decimal::operator = (f64 dec)
 
255
{
 
256
        m_value = round(static_cast<f64>(factor()) * dec);
 
257
        return *this;
 
258
}
 
259
 
 
260
decimal& decimal::operator = (f32 dec)
 
261
{
 
262
        m_value = round(static_cast<f64>(factor()) * dec);
 
263
        return *this;
 
264
}
 
265
 
 
266
bool decimal::operator == (const decimal& dec) const
 
267
{
 
268
        return m_value == convert(dec);
 
269
}
 
270
 
 
271
bool decimal::operator < (const decimal& dec) const
 
272
{
 
273
        return m_value < convert(dec);
 
274
}
 
275
 
 
276
bool decimal::operator <= (const decimal& dec) const
 
277
{
 
278
        return m_value <= convert(dec);
 
279
}
 
280
 
 
281
bool decimal::operator > (const decimal& dec) const
 
282
{
 
283
        return m_value > convert(dec);
 
284
}
 
285
 
 
286
bool decimal::operator >= (const decimal& dec) const
 
287
{
 
288
        return m_value >= convert(dec);
 
289
}
 
290
 
 
291
bool decimal::operator != (const decimal& dec) const
 
292
{
 
293
        return !(*this == dec);
 
294
}
 
295
 
 
296
const decimal decimal::operator + (const decimal& dec) const
 
297
{
 
298
        decimal result = *this;
 
299
        result.m_value += convert(dec);
 
300
        return result;
 
301
}
 
302
 
 
303
decimal& decimal::operator += (const decimal& dec)
 
304
{
 
305
        m_value += convert(dec);
 
306
        return *this;
 
307
}
 
308
 
 
309
const decimal decimal::operator - (const decimal& dec) const
 
310
{
 
311
        decimal result = *this;
 
312
        result.m_value -= convert(dec);
 
313
        return result;
 
314
}
 
315
 
 
316
decimal& decimal::operator -= (const decimal& dec)
 
317
{
 
318
        m_value -= convert(dec);
 
319
        return *this;
 
320
}
 
321
 
 
322
const decimal decimal::operator * (const decimal& dec) const
 
323
{
 
324
        decimal result = *this;
 
325
        multiply_divide(result.m_value, convert(dec), factor());
 
326
        return result;
 
327
}
 
328
 
 
329
decimal& decimal::operator *= (const decimal& dec)
 
330
{
 
331
        m_value = multiply_divide(m_value, convert(dec), factor());
 
332
        return *this;
 
333
}
 
334
 
 
335
const decimal decimal::operator / (const decimal& dec) const
 
336
{
 
337
        decimal result = *this;
 
338
        result.m_value = multiply_divide(result.m_value, factor(), convert(dec));
 
339
        return result;
 
340
}
 
341
 
 
342
decimal& decimal::operator /= (const decimal& dec)
 
343
{
 
344
        m_value = multiply_divide(m_value, factor(), convert(dec));
 
345
        return *this;
 
346
}