1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1
/* Copyright (C) 2005-2006 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
23
19
It is interface module to fixed precision decimals library.
25
Most functions use 'uint32_t mask' as parameter, if during operation error
21
Most functions use 'uint mask' as parameter, if during operation error
26
22
which fit in this mask is detected then it will be processed automatically
27
23
here. (errors are E_DEC_* constants, see include/decimal.h)
32
28
#ifndef my_decimal_h
33
29
#define my_decimal_h
39
#include <mystrings/decimal.h>
46
35
#define DECIMAL_LONGLONG_DIGITS 22
47
36
#define DECIMAL_LONG_DIGITS 10
48
37
#define DECIMAL_LONG3_DIGITS 8
50
/** maximum length of buffer in our big digits (uint32_t). */
39
/** maximum length of buffer in our big digits (uint32). */
51
40
#define DECIMAL_BUFF_LENGTH 9
53
42
/* the number of digits that my_decimal can possibly contain */
111
100
len= DECIMAL_BUFF_LENGTH;
113
#if !defined (HAVE_purify)
102
#if !defined (HAVE_purify) && !defined(DBUG_OFF)
114
103
/* Set buffer to 'random' value to find wrong buffer usage */
115
for (uint32_t i= 0; i < DECIMAL_BUFF_LENGTH; i++)
104
for (uint i= 0; i < DECIMAL_BUFF_LENGTH; i++)
125
114
bool sign() const { return decimal_t::sign; }
126
115
void sign(bool s) { decimal_t::sign= s; }
127
uint32_t precision() const { return intg + frac; }
116
uint precision() const { return intg + frac; }
121
void print_decimal(const my_decimal *dec);
122
void print_decimal_buff(const my_decimal *dec, const uchar* ptr, int length);
123
const char *dbug_decimal_as_string(char *buff, const my_decimal *val);
125
#define dbug_decimal_as_string(A) NULL
130
129
int decimal_operation_results(int result);
131
inline int decimal_operation_results(int result)
135
#endif /*MYSQL_CLIENT*/
133
138
void max_my_decimal(my_decimal *to, int precision, int frac)
135
assert((precision <= DECIMAL_MAX_PRECISION)&&
140
DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION)&&
136
141
(frac <= DECIMAL_MAX_SCALE));
137
142
max_decimal(precision, frac, (decimal_t*) to);
142
147
max_my_decimal(to, DECIMAL_MAX_PRECISION, 0);
145
inline int check_result(uint32_t mask, int result)
150
inline int check_result(uint mask, int result)
147
152
if (result & mask)
148
153
decimal_operation_results(result);
152
inline int check_result_and_overflow(uint32_t mask, int result, my_decimal *val)
157
inline int check_result_and_overflow(uint mask, int result, my_decimal *val)
154
159
if (check_result(mask, result) & E_DEC_OVERFLOW)
164
inline uint32_t my_decimal_length_to_precision(uint32_t length, uint32_t scale,
169
inline uint my_decimal_length_to_precision(uint length, uint scale,
165
170
bool unsigned_flag)
167
172
return (uint) (length - (scale>0 ? 1:0) - (unsigned_flag ? 0:1));
170
inline uint32_t my_decimal_precision_to_length(uint32_t precision, uint8_t scale,
175
inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale,
171
176
bool unsigned_flag)
173
178
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
174
return (uint32_t)(precision + (scale>0 ? 1:0) + (unsigned_flag ? 0:1));
179
return (uint32)(precision + (scale>0 ? 1:0) + (unsigned_flag ? 0:1));
207
int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
212
int my_decimal2binary(uint mask, const my_decimal *d, uchar *bin, int prec,
212
int binary2my_decimal(uint32_t mask, const unsigned char *bin, my_decimal *d, int prec,
217
int binary2my_decimal(uint mask, const uchar *bin, my_decimal *d, int prec,
215
220
return check_result(mask, bin2decimal(bin, (decimal_t*) d, prec, scale));
235
int my_decimal_round(uint32_t mask, const my_decimal *from, int scale,
240
int my_decimal_round(uint mask, const my_decimal *from, int scale,
236
241
bool truncate, my_decimal *to)
238
243
return check_result(mask, decimal_round((decimal_t*) from, to, scale,
244
int my_decimal_floor(uint32_t mask, const my_decimal *from, my_decimal *to)
249
int my_decimal_floor(uint mask, const my_decimal *from, my_decimal *to)
246
251
return check_result(mask, decimal_round((decimal_t*) from, to, 0, FLOOR));
251
int my_decimal_ceiling(uint32_t mask, const my_decimal *from, my_decimal *to)
256
int my_decimal_ceiling(uint mask, const my_decimal *from, my_decimal *to)
253
258
return check_result(mask, decimal_round((decimal_t*) from, to, 0, CEILING));
257
int my_decimal2string(uint32_t mask, const my_decimal *d, uint32_t fixed_prec,
258
uint32_t fixed_dec, char filler, String *str);
263
int my_decimal2string(uint mask, const my_decimal *d, uint fixed_prec,
264
uint fixed_dec, char filler, String *str);
261
int my_decimal2int(uint32_t mask, const my_decimal *d, bool unsigned_flag,
268
int my_decimal2int(uint mask, const my_decimal *d, my_bool unsigned_flag,
264
271
my_decimal rounded;
265
272
/* decimal_round can return only E_DEC_TRUNCATED */
266
273
decimal_round((decimal_t*)d, &rounded, 0, HALF_UP);
267
274
return check_result(mask, (unsigned_flag ?
268
decimal2uint64_t(&rounded, (uint64_t *)l) :
269
decimal2int64_t(&rounded, l)));
275
decimal2ulonglong(&rounded, (ulonglong *)l) :
276
decimal2longlong(&rounded, l)));
274
int my_decimal2double(uint32_t mask __attribute__((unused)),
275
const my_decimal *d, double *result)
281
int my_decimal2double(uint mask, const my_decimal *d, double *result)
277
283
/* No need to call check_result as this will always succeed */
278
284
return decimal2double((decimal_t*) d, result);
283
int str2my_decimal(uint32_t mask, char *str, my_decimal *d, char **end)
289
int str2my_decimal(uint mask, const char *str, my_decimal *d, char **end)
285
291
return check_result_and_overflow(mask, string2decimal(str,(decimal_t*)d,end),
290
int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
291
const CHARSET_INFO * charset, my_decimal *decimal_value);
296
int str2my_decimal(uint mask, const char *from, uint length,
297
CHARSET_INFO *charset, my_decimal *decimal_value);
293
#if defined(DRIZZLE_SERVER)
299
#if defined(MYSQL_SERVER)
295
int string2my_decimal(uint32_t mask, const String *str, my_decimal *d)
301
int string2my_decimal(uint mask, const String *str, my_decimal *d)
297
303
return str2my_decimal(mask, str->ptr(), str->length(), str->charset(), d);
301
my_decimal *date2my_decimal(DRIZZLE_TIME *ltime, my_decimal *dec);
304
#endif /*defined(DRIZZLE_SERVER) */
307
my_decimal *date2my_decimal(MYSQL_TIME *ltime, my_decimal *dec);
310
#endif /*defined(MYSQL_SERVER) */
307
int double2my_decimal(uint32_t mask, double val, my_decimal *d)
313
int double2my_decimal(uint mask, double val, my_decimal *d)
309
315
return check_result_and_overflow(mask, double2decimal(val, (decimal_t*)d), d);
314
int int2my_decimal(uint32_t mask, int64_t i, bool unsigned_flag, my_decimal *d)
320
int int2my_decimal(uint mask, longlong i, my_bool unsigned_flag, my_decimal *d)
316
322
return check_result(mask, (unsigned_flag ?
317
uint64_t2decimal((uint64_t)i, d) :
318
int64_t2decimal(i, d)));
323
ulonglong2decimal((ulonglong)i, d) :
324
longlong2decimal(i, d)));
335
int my_decimal_add(uint32_t mask, my_decimal *res, const my_decimal *a,
341
int my_decimal_add(uint mask, my_decimal *res, const my_decimal *a,
336
342
const my_decimal *b)
338
344
return check_result_and_overflow(mask,
345
int my_decimal_sub(uint32_t mask, my_decimal *res, const my_decimal *a,
351
int my_decimal_sub(uint mask, my_decimal *res, const my_decimal *a,
346
352
const my_decimal *b)
348
354
return check_result_and_overflow(mask,
355
int my_decimal_mul(uint32_t mask, my_decimal *res, const my_decimal *a,
361
int my_decimal_mul(uint mask, my_decimal *res, const my_decimal *a,
356
362
const my_decimal *b)
358
364
return check_result_and_overflow(mask,
365
int my_decimal_div(uint32_t mask, my_decimal *res, const my_decimal *a,
371
int my_decimal_div(uint mask, my_decimal *res, const my_decimal *a,
366
372
const my_decimal *b, int div_scale_inc)
368
374
return check_result_and_overflow(mask,
376
int my_decimal_mod(uint32_t mask, my_decimal *res, const my_decimal *a,
382
int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a,
377
383
const my_decimal *b)
379
385
return check_result_and_overflow(mask,