forked from vozbu/libslave
-
Notifications
You must be signed in to change notification settings - Fork 1
/
decimal.h
58 lines (45 loc) · 1.71 KB
/
decimal.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#pragma once
#include <stdint.h>
#include <iosfwd>
#include <string>
#include <utility>
namespace slave::decimal
{
// @brief digits container type
using digit_t = uint32_t;
static_assert(sizeof(digit_t) == 4);
// @brief structure to store mysql decimal value
// for more details see see https://dev.mysql.com/doc/refman/5.7/en/precision-math-decimal-characteristics.html
// @note struct should contain only pod - types, because it's internals are used directly (for the instance by memset)
struct Decimal
{
// the max number of digits which can be stored
static constexpr size_t max_digits = 65;
uint8_t storage[30]; // each 4 byte are used to store 9 digits and each 1 byte for 2 digits
uint8_t intg; // count of digits before point
uint8_t frac : 7; // count of digits after point
uint8_t sign : 1; // 0 - positive, 1 - negative
#ifdef SLAVE_USE_DOUBLE_AS_DECIMAL
// implicit conversion to double (used for backward compatibility)
operator double() const;
#endif
};
static_assert(32 == sizeof(Decimal));
bool operator==(const Decimal& l, const Decimal& r);
inline bool operator!=(const Decimal& l, const Decimal& r)
{
return !(l == r);
}
// @brief print decimal to ostream
std::ostream& operator<<(std::ostream& os, const Decimal& d);
// @brief strignify decimal value (used in strignify)
std::string to_string(const Decimal& d);
// @brief convert decimal to double
double to_double(const Decimal& d);
#ifdef SLAVE_USE_DOUBLE_AS_DECIMAL
inline Decimal::operator double() const
{
return to_double(*this);
}
#endif // SLAVE_USE_DOUBLE_AS_DECIMAL
}