4
// Author : Sylvain Rochette Langlois
5
// License : Boost Software License (http://www.boost.org/users/license.html)
12
#include <boost/lexical_cast.hpp>
13
#include <mariadb++/decimal.hpp>
15
using namespace mariadb;
20
// Result = (value1 * value2) / divider
22
s64 multiply_divide(s64 value1, s64 value2, s64 divider)
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));
27
return round(static_cast<f64>(value1) * static_cast<f64>(value2) / static_cast<f64>(divider));
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)),
107
decimal::decimal(const decimal& src) :
108
m_precision(src.m_precision),
113
decimal::decimal(const char* string) :
118
// Extract the amount of precision required
120
std::string str = string;
121
size_t pos = str.find(".");
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));
129
m_value = boost::lexical_cast<s64>(string);
135
s64 decimal::factor() const
137
return g_factors[m_precision];
140
u8 decimal::precision() const
146
// Convert a decimal to the same precision as this one
148
s64 decimal::convert(const decimal& dec) const
150
if (m_precision == dec.m_precision)
153
return (dec.m_value / dec.factor()) * factor();
156
decimal decimal::abs() const
161
return decimal(0, factor()) - *this;
167
int decimal::compare(const decimal& dec) const
169
const s64 b = convert(dec);
183
std::string decimal::str() const
185
s64 after = m_value % factor();
186
s64 before = (m_value - after) / factor();
188
std::ostringstream out;
189
out << before << '.' << std::setw(m_precision) << std::setfill('0') << std::right << after;
196
f32 decimal::float32() const
198
return static_cast<f32>(m_value) / static_cast<f32>(m_precision * factor());
201
f64 decimal::double64() const
203
return static_cast<f64>(m_value) / static_cast<f64>(m_precision * factor());
206
f128 decimal::double128() const
208
return static_cast<f128>(m_value) / static_cast<f128>(m_precision * factor());
212
// Returns interget value = real_value * (10 ^ precision)
214
s64 decimal::unbiased() const
222
decimal& decimal::operator = (const decimal& dec)
225
m_value = convert(dec);
230
decimal& decimal::operator = (s64 dec)
232
m_value = factor() * dec;
236
decimal& decimal::operator = (s32 dec)
238
m_value = factor() * dec;
242
decimal& decimal::operator = (f64 dec)
244
m_value = round(static_cast<f64>(factor()) * dec);
248
decimal& decimal::operator = (f32 dec)
250
m_value = round(static_cast<f64>(factor()) * dec);
254
bool decimal::operator == (const decimal& dec) const
256
return m_value == convert(dec);
259
bool decimal::operator < (const decimal& dec) const
261
return m_value < convert(dec);
264
bool decimal::operator <= (const decimal& dec) const
266
return m_value <= convert(dec);
269
bool decimal::operator > (const decimal& dec) const
271
return m_value > convert(dec);
274
bool decimal::operator >= (const decimal& dec) const
276
return m_value >= convert(dec);
279
bool decimal::operator != (const decimal& dec) const
281
return !(*this == dec);
284
const decimal decimal::operator + (const decimal& dec) const
286
decimal result = *this;
287
result.m_value += convert(dec);
291
decimal& decimal::operator += (const decimal& dec)
293
m_value += convert(dec);
297
const decimal decimal::operator - (const decimal& dec) const
299
decimal result = *this;
300
result.m_value -= convert(dec);
304
decimal& decimal::operator -= (const decimal& dec)
306
m_value -= convert(dec);
310
const decimal decimal::operator * (const decimal& dec) const
312
decimal result = *this;
313
multiply_divide(result.m_value, convert(dec), factor());
317
decimal& decimal::operator *= (const decimal& dec)
319
m_value = multiply_divide(m_value, convert(dec), factor());
323
const decimal decimal::operator / (const decimal& dec) const
325
decimal result = *this;
326
result.m_value = multiply_divide(result.m_value, factor(), convert(dec));
330
decimal& decimal::operator /= (const decimal& dec)
332
m_value = multiply_divide(m_value, factor(), convert(dec));
4
// Author : Sylvain Rochette Langlois
5
// License : Boost Software License (http://www.boost.org/users/license.html)
12
#include <boost/lexical_cast.hpp>
13
#include <mariadb++/decimal.hpp>
16
#ifdef MARIADB_WITHOUT_CPP11
19
template <typename type>
20
mariadb::s64 round(type value)
22
return mariadb::s64(value < 0.0 ? value - 0.5 : value + 0.5);
27
using namespace mariadb;
32
// Result = (value1 * value2) / divider
34
s64 multiply_divide(s64 value1, s64 value2, s64 divider)
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));
39
return round(static_cast<f64>(value1)* static_cast<f64>(value2) / static_cast<f64>(divider));
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)),
119
decimal::decimal(const decimal& src) :
120
m_precision(src.m_precision),
125
decimal::decimal(const char* string) :
130
// Extract the amount of precision required
132
std::string str = string;
133
size_t pos = str.find(".");
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));
141
m_value = boost::lexical_cast<s64>(string);
147
s64 decimal::factor() const
149
return g_factors[m_precision];
152
u8 decimal::precision() const
158
// Convert a decimal to the same precision as this one
160
s64 decimal::convert(const decimal& dec) const
162
if (m_precision == dec.m_precision)
165
return (dec.m_value / dec.factor()) * factor();
168
decimal decimal::abs() const
173
return decimal(0, static_cast<u8>(factor())) - *this;
179
int decimal::compare(const decimal& dec) const
181
const s64 b = convert(dec);
195
std::string decimal::str() const
197
s64 after = m_value % factor();
198
s64 before = (m_value - after) / factor();
200
std::ostringstream out;
201
out << before << '.' << std::setw(m_precision) << std::setfill('0') << std::right << after;
208
f32 decimal::float32() const
210
return static_cast<f32>(m_value) / static_cast<f32>(m_precision * factor());
213
f64 decimal::double64() const
215
return static_cast<f64>(m_value) / static_cast<f64>(m_precision * factor());
218
f128 decimal::double128() const
220
return static_cast<f128>(m_value) / static_cast<f128>(m_precision * factor());
224
// Returns interget value = real_value * (10 ^ precision)
226
s64 decimal::unbiased() const
234
decimal& decimal::operator = (const decimal& dec)
237
m_value = convert(dec);
242
decimal& decimal::operator = (s64 dec)
244
m_value = factor() * dec;
248
decimal& decimal::operator = (s32 dec)
250
m_value = factor() * dec;
254
decimal& decimal::operator = (f64 dec)
256
m_value = round(static_cast<f64>(factor()) * dec);
260
decimal& decimal::operator = (f32 dec)
262
m_value = round(static_cast<f64>(factor()) * dec);
266
bool decimal::operator == (const decimal& dec) const
268
return m_value == convert(dec);
271
bool decimal::operator < (const decimal& dec) const
273
return m_value < convert(dec);
276
bool decimal::operator <= (const decimal& dec) const
278
return m_value <= convert(dec);
281
bool decimal::operator > (const decimal& dec) const
283
return m_value > convert(dec);
286
bool decimal::operator >= (const decimal& dec) const
288
return m_value >= convert(dec);
291
bool decimal::operator != (const decimal& dec) const
293
return !(*this == dec);
296
const decimal decimal::operator + (const decimal& dec) const
298
decimal result = *this;
299
result.m_value += convert(dec);
303
decimal& decimal::operator += (const decimal& dec)
305
m_value += convert(dec);
309
const decimal decimal::operator - (const decimal& dec) const
311
decimal result = *this;
312
result.m_value -= convert(dec);
316
decimal& decimal::operator -= (const decimal& dec)
318
m_value -= convert(dec);
322
const decimal decimal::operator * (const decimal& dec) const
324
decimal result = *this;
325
multiply_divide(result.m_value, convert(dec), factor());
329
decimal& decimal::operator *= (const decimal& dec)
331
m_value = multiply_divide(m_value, convert(dec), factor());
335
const decimal decimal::operator / (const decimal& dec) const
337
decimal result = *this;
338
result.m_value = multiply_divide(result.m_value, factor(), convert(dec));
342
decimal& decimal::operator /= (const decimal& dec)
344
m_value = multiply_divide(m_value, factor(), convert(dec));