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
26typedef enum
27{TRUNCATE=0, HALF_EVEN, HALF_UP, CEILING, FLOOR}
28 decimal_round_mode;
29typedef 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 */
40typedef 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
47int internal_str2dec(const char *from, decimal_t *to, char **end,
48 my_bool fixed);
49int decimal2string(const decimal_t *from, char *to, int *to_len,
50 int fixed_precision, int fixed_decimals,
51 char filler);
52int decimal2ulonglong(decimal_t *from, ulonglong *to);
53int ulonglong2decimal(ulonglong from, decimal_t *to);
54int decimal2longlong(decimal_t *from, longlong *to);
55int longlong2decimal(longlong from, decimal_t *to);
56int decimal2double(const decimal_t *from, double *to);
57int double2decimal(double from, decimal_t *to);
58int decimal_actual_fraction(decimal_t *from);
59int decimal2bin(decimal_t *from, uchar *to, int precision, int scale);
60int 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*/
71int 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
83int double2lldiv_t(double from, lldiv_t *to);
84int decimal_size(int precision, int scale);
85int decimal_bin_size(int precision, int scale);
86int decimal_result_size(decimal_t *from1, decimal_t *from2, char op,
87 int param);
88
89int decimal_intg(const decimal_t *from);
90int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to);
91int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to);
92int decimal_cmp(const decimal_t *from1, const decimal_t *from2);
93int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to);
94int decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to,
95 int scale_incr);
96int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to);
97int decimal_round(const decimal_t *from, decimal_t *to, int new_scale,
98 decimal_round_mode mode);
99int decimal_is_zero(const decimal_t *from);
100void 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