-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmydecimal.h
132 lines (93 loc) · 3.78 KB
/
mydecimal.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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#ifndef MY_DECIMAL_H
#define MY_DECIMAL_H
#include <string.h>
#include "myconvert.h"
#define DIG_PER_DEC1 9
#define E_DEC_TRUNCATED 1
#define E_DEC_OVERFLOW 2
#define E_DEC_FATAL_ERROR 30
#define DECIMAL_BUFF_LENGTH 9
#define swap_variables(t, a, b) { t dummy; dummy= a; a= b; b= dummy; }
#define E_DEC_OK 0
#define UNINIT_VAR(x) x= 0
#define FIX_INTG_FRAC_ERROR(len, intg1, frac1, error) \
do \
{ \
if (unlikely(intg1+frac1 > (len))) \
{ \
if (unlikely(intg1 > (len))) \
{ \
intg1=(len); \
frac1=0; \
error=E_DEC_OVERFLOW; \
} \
else \
{ \
frac1=(len)-intg1; \
error=E_DEC_TRUNCATED; \
} \
} \
else \
error=E_DEC_OK; \
} while(0)
#define __builtin_expect(x, expected_value) (x)
#define unlikely(x) __builtin_expect((x),0)
#define DIG_BASE 1000000000
#define DIG_MAX (DIG_BASE-1)
#define decimal_make_zero(dec) do { \
(dec)->buf[0]=0; \
(dec)->intg=1; \
(dec)->frac=0; \
(dec)->sign=0; \
} while(0)
#define E_DEC_BAD_NUM 8
#define ROUND_UP(X) (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
typedef int32 decimal_digit_t;
typedef decimal_digit_t dec1;
static const int dig2bytes[DIG_PER_DEC1+1]={0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
static const dec1 powers10[DIG_PER_DEC1+1]={
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
int decimal_operation_results(int result);
int decimal_bin_size(int precision, int scale);
int my_decimal_get_binary_size(uint precision, uint scale);
int check_result(uint mask, int result);
typedef struct st_decimal_t {
int intg, frac, len;
bool sign;
decimal_digit_t *buf;
} decimal_t;
class my_decimal :public decimal_t
{
decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
public:
void init()
{
len= DECIMAL_BUFF_LENGTH;
buf= buffer;
#if !defined (HAVE_purify) && !defined(DBUG_OFF)
/* Set buffer to 'random' value to find wrong buffer usage */
for (uint i= 0; i < DECIMAL_BUFF_LENGTH; i++)
buffer[i]= i;
#endif
}
my_decimal()
{
init();
}
void fix_buffer_pointer() { buf= buffer; }
bool sign() const { return decimal_t::sign; }
void sign(bool s) { decimal_t::sign= s; }
uint precision() const { return intg + frac; }
/** Swap two my_decimal values */
void swap(my_decimal &rhs)
{
swap_variables(my_decimal, *this, rhs);
/* Swap the buffer pointers back */
swap_variables(decimal_digit_t *, buf, rhs.buf);
}
};
#define my_alloca(A) my_malloc((A),MYF(0))
#define my_afree(A) my_free((A))
int bin2decimal(const unsigned char *from, decimal_t *to, int precision, int scale);
int binary2my_decimal(uint8 mask, const unsigned char *bin, my_decimal *d, int prec, int scale);
#endif