1 | /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. |
2 | |
3 | This program is free software; you can redistribute it and/or modify |
4 | it under the terms of the GNU General Public License, version 2.0, |
5 | as published by the Free Software Foundation. |
6 | |
7 | This program is also distributed with certain software (including |
8 | but not limited to OpenSSL) that is licensed under separate terms, |
9 | as designated in a particular file or component or in included license |
10 | documentation. The authors of MySQL hereby grant you an additional |
11 | permission to link the program and your derivative works with the |
12 | separately licensed software that they have included with MySQL. |
13 | |
14 | This program is distributed in the hope that it will be useful, |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | GNU General Public License, version 2.0, for more details. |
18 | |
19 | You should have received a copy of the GNU General Public License |
20 | along with this program; if not, write to the Free Software |
21 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
22 | |
23 | #ifndef DECIMAL_INCLUDED |
24 | #define DECIMAL_INCLUDED |
25 | |
26 | typedef enum |
27 | {TRUNCATE=0, HALF_EVEN, HALF_UP, CEILING, FLOOR} |
28 | decimal_round_mode; |
29 | typedef int32 decimal_digit_t; |
30 | |
31 | /** |
32 | intg is the number of *decimal* digits (NOT number of decimal_digit_t's !) |
33 | before the point |
34 | frac is the number of decimal digits after the point |
35 | len is the length of buf (length of allocated space) in decimal_digit_t's, |
36 | not in bytes |
37 | sign false means positive, true means negative |
38 | buf is an array of decimal_digit_t's |
39 | */ |
40 | typedef struct st_decimal_t { |
41 | int intg, frac, len; |
42 | my_bool sign; |
43 | decimal_digit_t *buf; |
44 | } decimal_t; |
45 | |
46 | #ifndef MYSQL_ABI_CHECK |
47 | int internal_str2dec(const char *from, decimal_t *to, char **end, |
48 | my_bool fixed); |
49 | int decimal2string(const decimal_t *from, char *to, int *to_len, |
50 | int fixed_precision, int fixed_decimals, |
51 | char filler); |
52 | int decimal2ulonglong(decimal_t *from, ulonglong *to); |
53 | int ulonglong2decimal(ulonglong from, decimal_t *to); |
54 | int decimal2longlong(decimal_t *from, longlong *to); |
55 | int longlong2decimal(longlong from, decimal_t *to); |
56 | int decimal2double(const decimal_t *from, double *to); |
57 | int double2decimal(double from, decimal_t *to); |
58 | int decimal_actual_fraction(decimal_t *from); |
59 | int decimal2bin(decimal_t *from, uchar *to, int precision, int scale); |
60 | int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale); |
61 | |
62 | /** |
63 | Convert decimal to lldiv_t. |
64 | The integer part is stored in to->quot. |
65 | The fractional part is multiplied to 10^9 and stored to to->rem. |
66 | @param from Decimal value |
67 | @param to lldiv_t value |
68 | @retval 0 on success |
69 | @retval !0 in error |
70 | */ |
71 | int decimal2lldiv_t(const decimal_t *from, lldiv_t *to); |
72 | |
73 | /** |
74 | Convert doube to lldiv_t. |
75 | The integer part is stored in to->quot. |
76 | The fractional part is multiplied to 10^9 and stored to to->rem. |
77 | @param from Decimal value |
78 | @param to lldiv_t value |
79 | @retval 0 on success |
80 | @retval !0 in error |
81 | */ |
82 | |
83 | int double2lldiv_t(double from, lldiv_t *to); |
84 | int decimal_size(int precision, int scale); |
85 | int decimal_bin_size(int precision, int scale); |
86 | int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, |
87 | int param); |
88 | |
89 | int decimal_intg(const decimal_t *from); |
90 | int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to); |
91 | int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to); |
92 | int decimal_cmp(const decimal_t *from1, const decimal_t *from2); |
93 | int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to); |
94 | int decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, |
95 | int scale_incr); |
96 | int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to); |
97 | int decimal_round(const decimal_t *from, decimal_t *to, int new_scale, |
98 | decimal_round_mode mode); |
99 | int decimal_is_zero(const decimal_t *from); |
100 | void max_decimal(int precision, int frac, decimal_t *to); |
101 | |
102 | #define string2decimal(A,B,C) internal_str2dec((A), (B), (C), 0) |
103 | #define string2decimal_fixed(A,B,C) internal_str2dec((A), (B), (C), 1) |
104 | |
105 | /* set a decimal_t to zero */ |
106 | |
107 | #define decimal_make_zero(dec) do { \ |
108 | (dec)->buf[0]=0; \ |
109 | (dec)->intg=1; \ |
110 | (dec)->frac=0; \ |
111 | (dec)->sign=0; \ |
112 | } while(0) |
113 | |
114 | /* |
115 | returns the length of the buffer to hold string representation |
116 | of the decimal (including decimal dot, possible sign and \0) |
117 | */ |
118 | |
119 | #define decimal_string_size(dec) (((dec)->intg ? (dec)->intg : 1) + \ |
120 | (dec)->frac + ((dec)->frac > 0) + 2) |
121 | |
122 | /* |
123 | conventions: |
124 | |
125 | decimal_smth() == 0 -- everything's ok |
126 | decimal_smth() <= 1 -- result is usable, but precision loss is possible |
127 | decimal_smth() <= 2 -- result can be unusable, most significant digits |
128 | could've been lost |
129 | decimal_smth() > 2 -- no result was generated |
130 | */ |
131 | |
132 | #define E_DEC_OK 0 |
133 | #define E_DEC_TRUNCATED 1 |
134 | #define E_DEC_OVERFLOW 2 |
135 | #define E_DEC_DIV_ZERO 4 |
136 | #define E_DEC_BAD_NUM 8 |
137 | #define E_DEC_OOM 16 |
138 | |
139 | #define E_DEC_ERROR 31 |
140 | #define E_DEC_FATAL_ERROR 30 |
141 | |
142 | #endif // !MYSQL_ABI_CHECK |
143 | |
144 | #endif |
145 | |