103
97
implementation-defined.
108
#include "drizzled/definitions.h"
109
#include "drizzled/internal/m_string.h"
110
#include "drizzled/charset_info.h"
111
#include "drizzled/decimal.h"
113
#include <plugin/myisam/myisampack.h>
100
#include <drizzled/global.h>
102
#include "m_string.h"
106
#include <storage/myisam/myisampack.h>
114
107
#include <drizzled/util/test.h>
117
109
#include <alloca.h>
122
#include "drizzled/current_session.h"
123
#include "drizzled/error.h"
124
#include "drizzled/field.h"
125
#include "drizzled/internal/my_sys.h"
132
report result of decimal operation.
134
@param result decimal library return code (E_DEC_* see include/decimal.h)
143
int decimal_operation_results(int result)
148
case E_DEC_TRUNCATED:
149
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
150
ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED),
154
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
155
ER_TRUNCATED_WRONG_VALUE,
156
ER(ER_TRUNCATED_WRONG_VALUE),
160
my_error(ER_DIVISION_BY_ZERO, MYF(0));
163
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
164
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
165
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
166
"decimal", "", "", (long)-1);
169
my_error(ER_OUT_OF_RESOURCES, MYF(0));
179
@brief Converting decimal to string
181
@details Convert given my_decimal to String; allocate buffer as needed.
183
@param[in] mask what problems to warn on (mask of E_DEC_* values)
184
@param[in] d the decimal to print
185
@param[in] fixed_prec overall number of digits if ZEROFILL, 0 otherwise
186
@param[in] fixed_dec number of decimal places (if fixed_prec != 0)
187
@param[in] filler what char to pad with (ZEROFILL et al.)
188
@param[out] *str where to store the resulting string
192
@retval E_DEC_TRUNCATED
193
@retval E_DEC_OVERFLOW
197
int my_decimal2string(uint32_t mask, const my_decimal *d,
198
uint32_t fixed_prec, uint32_t fixed_dec,
199
char filler, String *str)
202
Calculate the size of the string: For DECIMAL(a,b), fixed_prec==a
203
holds true iff the type is also ZEROFILL, which in turn implies
204
UNSIGNED. Hence the buffer for a ZEROFILLed value is the length
205
the user requested, plus one for a possible decimal point, plus
206
one if the user only wanted decimal places, but we force a leading
207
zero on them. Because the type is implicitly UNSIGNED, we do not
208
need to reserve a character for the sign. For all other cases,
209
fixed_prec will be 0, and my_decimal_string_length() will be called
210
instead to calculate the required size of the buffer.
212
int length= (int)(fixed_prec
213
? (uint32_t)(fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1)
214
: (uint32_t)my_decimal_string_length(d));
216
if (str->alloc(length))
217
return check_result(mask, E_DEC_OOM);
218
result= decimal2string((decimal_t*) d, (char*) str->ptr(),
219
&length, (int)fixed_prec, fixed_dec,
222
return check_result(mask, result);
227
@brief Convert from decimal to binary representation
229
@param[in] mask error processing mask
230
@param[in] d number for conversion
231
@param[out] bin pointer to buffer where to write result
232
@param[in] prec overall number of decimal digits
233
@param[in] scale number of decimal digits after decimal point
236
Before conversion we round number if it need but produce truncation
241
@retval E_DEC_TRUNCATED
242
@retval E_DEC_OVERFLOW
245
int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
248
int err1= E_DEC_OK, err2;
250
my_decimal2decimal(d, &rounded);
251
rounded.frac= decimal_actual_fraction(&rounded);
252
if (scale < rounded.frac)
254
err1= E_DEC_TRUNCATED;
255
/* decimal_round can return only E_DEC_TRUNCATED */
256
decimal_round(&rounded, &rounded, scale, HALF_UP);
258
err2= decimal2bin(&rounded, bin, prec, scale);
261
return check_result(mask, err2);
266
@brief Convert string for decimal when string can be in some multibyte charset
268
@param mask error processing mask
269
@param from string to process
270
@param length length of given string
271
@param charset charset of given string
272
@param decimal_value buffer for result storing
276
@retval E_DEC_TRUNCATED
277
@retval E_DEC_OVERFLOW
278
@retval E_DEC_BAD_NUM
282
int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
283
const CHARSET_INFO * charset, my_decimal *decimal_value)
285
char *end, *from_end;
287
char buff[STRING_BUFFER_USUAL_SIZE];
288
String tmp(buff, sizeof(buff), &my_charset_bin);
289
if (charset->mbminlen > 1)
292
tmp.copy(from, length, charset, &my_charset_utf8_general_ci, &dummy_errors);
294
length= tmp.length();
295
charset= &my_charset_bin;
297
from_end= end= (char*) from+length;
298
err= string2decimal((char *)from, (decimal_t*) decimal_value, &end);
299
if (end != from_end && !err)
301
/* Give warning if there is something other than end space */
302
for ( ; end < from_end; end++)
304
if (!my_isspace(&my_charset_utf8_general_ci, *end))
306
err= E_DEC_TRUNCATED;
311
check_result_and_overflow(mask, err, decimal_value);
316
my_decimal *date2my_decimal(DRIZZLE_TIME *ltime, my_decimal *dec)
319
date = (ltime->year*100L + ltime->month)*100L + ltime->day;
320
if (ltime->time_type > DRIZZLE_TIMESTAMP_DATE)
321
date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second;
322
if (int2my_decimal(E_DEC_FATAL_ERROR, date, false, dec))
324
if (ltime->second_part)
326
dec->buf[(dec->intg-1) / 9 + 1]= ltime->second_part * 1000;
333
void my_decimal_trim(uint32_t *precision, uint32_t *scale)
335
if (!(*precision) && !(*scale))
345
111
Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
346
112
So one variable of type decimal_digit_t is limited:
378
138
999900000, 999990000, 999999000,
379
139
999999900, 999999990 };
382
142
#define sanity(d) assert((d)->len > 0)
384
144
#define sanity(d) assert((d)->len >0 && ((d)->buf[0] | \
385
145
(d)->buf[(d)->len-1] | 1))
388
inline static void fix_intg_frac_error(const int len, int &intg1, int &frac1, int &error)
390
if (unlikely(intg1+frac1 > len))
392
if (unlikely(intg1 > len))
396
error=E_DEC_OVERFLOW;
401
error=E_DEC_TRUNCATED;
408
/* assume carry <= 1 */
409
inline static void add(dec1 &to, const dec1 &from1, const dec1& from2, dec1 &carry)
411
dec1 a=from1+from2+carry;
413
if ((carry= (a >= DIG_BASE))) /* no division here! */
418
inline static void add2(dec1 &to, const dec1 &from1, const dec1 &from2, dec1 &carry)
420
dec2 a=dec2(from1)+from2+carry;
421
if ((carry= (a >= DIG_BASE)))
423
if (unlikely(a >= DIG_BASE))
432
inline static void sub(dec1 &to, const dec1 &from1, const dec1 &from2, dec1 &carry)
434
dec1 a=from1-from2-carry;
435
if ((carry= (a < 0)))
441
inline static void sub2(dec1 &to, const dec1 &from1, const dec1 &from2, dec1 &carry)
443
dec1 a=from1-from2-carry;
444
if ((carry= (a < 0)))
148
#define FIX_INTG_FRAC_ERROR(len, intg1, frac1, error) \
151
if (unlikely(intg1+frac1 > (len))) \
153
if (unlikely(intg1 > (len))) \
157
error=E_DEC_OVERFLOW; \
162
error=E_DEC_TRUNCATED; \
169
#define ADD(to, from1, from2, carry) /* assume carry <= 1 */ \
172
dec1 a=(from1)+(from2)+(carry); \
173
assert((carry) <= 1); \
174
if (((carry)= a >= DIG_BASE)) /* no division here! */ \
179
#define ADD2(to, from1, from2, carry) \
182
dec2 a=((dec2)(from1))+(from2)+(carry); \
183
if (((carry)= a >= DIG_BASE)) \
185
if (unlikely(a >= DIG_BASE)) \
193
#define SUB(to, from1, from2, carry) /* to=from1-from2 */ \
196
dec1 a=(from1)-(from2)-(carry); \
197
if (((carry)= a < 0)) \
202
#define SUB2(to, from1, from2, carry) /* to=from1-from2 */ \
205
dec1 a=(from1)-(from2)-(carry); \
206
if (((carry)= a < 0)) \
208
if (unlikely(a < 0)) \
455
@brief Get maximum value for given precision and scale
457
@param precision/scale see decimal_bin_size() below
458
@param to decimal where where the result will be stored
217
Swap the contents of two variables.
219
#define swap_variables(TYPE, a, b) \
229
Get maximum value for given precision and scale
233
precision/scale - see decimal_bin_size() below
234
to - decimal where where the result will be stored
459
235
to->buf and to->len must be set.
542
@brief Convert decimal to its printable string representation
320
Convert decimal to its printable string representation
544
@param from value to convert
545
@param to points to buffer where string representation
547
@param to_len in: size of to buffer
548
out: length of the actually written string
549
@param fixed_precision 0 if representation can be variable length and
324
from - value to convert
325
to - points to buffer where string representation
327
*to_len - in: size of to buffer
328
out: length of the actually written string
329
fixed_precision - 0 if representation can be variable length and
550
330
fixed_decimals will not be checked in this case.
551
331
Put number as with fixed point position with this
552
332
number of digits (sign counted and decimal point is
554
@param fixed_decimals number digits after point.
555
@param filler character to fill gaps in case of fixed_precision > 0
334
fixed_decimals - number digits after point.
335
filler - character to fill gaps in case of fixed_precision > 0
559
@retval E_DEC_TRUNCATED
560
@retval E_DEC_OVERFLOW
338
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
562
int decimal2string(const decimal_t *from, char *to, int *to_len,
341
int decimal2string(decimal_t *from, char *to, int *to_len,
563
342
int fixed_precision, int fixed_decimals,
731
@param Left shift for alignment of data in buffer
733
@param dec pointer to decimal number which have to be shifted
734
@param shift number of decimal digits on which it should be shifted
735
@param beg beginning of decimal digits (see digits_bounds())
736
@param end end of decimal digits (see digits_bounds())
739
Result fitting in the buffer should be garanted.
740
'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
742
@todo Above note is unclear - is 'garanted' a typo for 'guaranteed'
513
Left shift for alignment of data in buffer
517
dec pointer to decimal number which have to be shifted
518
shift number of decimal digits on which it should be shifted
519
beg/end bounds of decimal digits (see digits_bounds())
522
Result fitting in the buffer should be garanted.
523
'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
745
526
static void do_mini_left_shift(decimal_t *dec, int shift, int beg, int last)
747
dec1 *from= dec->buf + round_up(beg + 1) - 1;
748
dec1 *end= dec->buf + round_up(last) - 1;
528
dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
529
dec1 *end= dec->buf + ROUND_UP(last) - 1;
749
530
int c_shift= DIG_PER_DEC1 - shift;
750
531
assert(from >= dec->buf);
751
532
assert(end < dec->buf + dec->len);
1176
965
rc = decimal2string(from, strbuf, &len, 0, 0, 0);
1177
966
end= strbuf + len;
1179
*to= internal::my_strtod(strbuf, &end, &error);
968
*to= my_strtod(strbuf, &end, &error);
1181
970
return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
1185
@param Convert double to decimal
1187
@param[in] from value to convert
1188
@param[out] to result will be stored there
974
Convert double to decimal
978
from - value to convert
979
to - result will be stored there
1191
982
E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1194
int double2decimal(const double from, decimal_t *to)
985
int double2decimal(double from, decimal_t *to)
1196
987
char buff[FLOATING_POINT_BUFFER], *end;
1198
end= buff + internal::my_gcvt(from,
1199
internal::MY_GCVT_ARG_DOUBLE,
1200
sizeof(buff) - 1, buff, NULL);
989
end= buff + my_gcvt(from, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
1201
990
res= string2decimal(buff, to, &end);
1641
1448
frac0*sizeof(dec1)+dig2bytes[frac0x];
1645
@brief Rounds the decimal to "scale" digits
1647
@param from - decimal to round,
1648
@param to - result buffer. from==to is allowed
1649
@param scale - to what position to round. can be negative!
1650
@param mode - round to nearest even or truncate
1452
Rounds the decimal to "scale" digits
1456
from - decimal to round,
1457
to - result buffer. from==to is allowed
1458
scale - to what position to round. can be negative!
1459
mode - round to nearest even or truncate
1653
1462
scale can be negative !
1654
1463
one TRUNCATED error (line XXX below) isn't treated very logical :(
1657
1466
E_DEC_OK/E_DEC_TRUNCATED
1660
decimal_round(const decimal_t *from, decimal_t *to, int scale,
1470
decimal_round(decimal_t *from, decimal_t *to, int scale,
1661
1471
decimal_round_mode mode)
1663
int frac0=scale>0 ? round_up(scale) : scale/DIG_PER_DEC1,
1664
frac1=round_up(from->frac), round_digit= 0,
1665
intg0=round_up(from->intg), error=E_DEC_OK, len=to->len,
1666
intg1=round_up(from->intg +
1473
int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
1474
frac1=ROUND_UP(from->frac), round_digit= 0,
1475
intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len,
1476
intg1=ROUND_UP(from->intg +
1667
1477
(((intg0 + frac0)>0) && (from->buf[0] == DIG_MAX)));
1668
1478
dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
1852
static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1854
int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
1855
frac1=round_up(from1->frac), frac2=round_up(from2->frac),
1856
frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
1663
Returns the size of the result of the operation
1666
decimal_result_size()
1667
from1 - operand of the unary operation or first operand of the
1669
from2 - second operand of the binary operation
1670
op - operation. one char '+', '-', '*', '/' are allowed
1671
others may be added later
1672
param - extra param to the operation. unused for '+', '-', '*'
1673
scale increment for '/'
1676
returned valued may be larger than the actual buffer requred
1677
in the operation, as decimal_result_size, by design, operates on
1678
precision/scale values only and not on the actual decimal number
1681
size of to->buf array in dec1 elements. to get size in bytes
1682
multiply by sizeof(dec1)
1685
int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, int param)
1689
return ROUND_UP(cmax(from1->intg, from2->intg)) +
1690
ROUND_UP(cmax(from1->frac, from2->frac));
1692
return ROUND_UP(cmax(from1->intg, from2->intg)+1) +
1693
ROUND_UP(cmax(from1->frac, from2->frac));
1695
return ROUND_UP(from1->intg+from2->intg)+
1696
ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
1698
return ROUND_UP(from1->intg+from2->intg+1+from1->frac+from2->frac+param);
1701
return -1; /* shut up the warning */
1704
static int do_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
1706
int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1707
frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1708
frac0=cmax(frac1, frac2), intg0=cmax(intg1, intg2), error;
1857
1709
dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
2077
int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1929
int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
2079
1931
if (likely(from1->sign == from2->sign))
2080
1932
return do_add(from1, from2, to);
2081
1933
return do_sub(from1, from2, to);
2084
int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1936
int decimal_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
2086
1938
if (likely(from1->sign == from2->sign))
2087
1939
return do_sub(from1, from2, to);
2088
1940
return do_add(from1, from2, to);
2091
int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
1943
int decimal_cmp(decimal_t *from1, decimal_t *from2)
2093
1945
if (likely(from1->sign == from2->sign))
2094
1946
return do_sub(from1, from2, 0);
2095
1947
return from1->sign > from2->sign ? -1 : 1;
2098
int decimal_is_zero(const decimal_t *from)
1950
int decimal_is_zero(decimal_t *from)
2100
1952
dec1 *buf1=from->buf,
2101
*end=buf1+round_up(from->intg)+round_up(from->frac);
1953
*end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
2102
1954
while (buf1 < end)
2109
@brief multiply two decimals
2111
@param[in] from1 First factor
2112
@param[in] from2 Second factor
2113
@param[out] to product
1961
multiply two decimals
1965
from1, from2 - factors
2116
1969
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW;
2119
1972
in this implementation, with sizeof(dec1)=4 we have DIG_PER_DEC1=9,
2120
1973
and 63-digit number will take only 7 dec1 words (basically a 7-digit
2121
1974
"base 999999999" number). Thus there's no need in fast multiplication
2125
1978
XXX if this library is to be used with huge numbers of thousands of
2126
1979
digits, fast multiplication must be implemented.
2128
int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1981
int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to)
2130
int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
2131
frac1=round_up(from1->frac), frac2=round_up(from2->frac),
2132
intg0=round_up(from1->intg+from2->intg),
1983
int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1984
frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1985
intg0=ROUND_UP(from1->intg+from2->intg),
2133
1986
frac0=frac1+frac2, error, i, j, d_to_move;
2134
1987
dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
2135
1988
*start2, *stop2, *stop1, *start0, carry;
2235
2088
naive division algorithm (Knuth's Algorithm D in 4.3.1) -
2236
2089
it's ok for short numbers
2237
2090
also we're using alloca() to allocate a temporary buffer
2240
If this library is to be used with huge numbers of thousands of
2092
XXX if this library is to be used with huge numbers of thousands of
2241
2093
digits, fast division must be implemented and alloca should be
2242
2094
changed to malloc (or at least fallback to malloc if alloca() fails)
2243
2095
but then, decimal_mul() should be rewritten too :(
2245
static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
2097
static int do_div_mod(decimal_t *from1, decimal_t *from2,
2246
2098
decimal_t *to, decimal_t *mod, int scale_incr)
2248
int frac1=round_up(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2249
frac2=round_up(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2100
int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2101
frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2250
2102
error= 0, i, intg0, frac0, len1, len2, dintg, div_mod=(!mod);
2251
2103
dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1,
2252
2104
*start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry;
2488
@brief division of two decimals
2490
@param[in] from1 dividend
2491
@param[in] from2 divisor
2492
@param[out] to quotient
2340
division of two decimals
2495
2349
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2498
2352
see do_div_mod()
2501
decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, int scale_incr)
2356
decimal_div(decimal_t *from1, decimal_t *from2, decimal_t *to, int scale_incr)
2503
2358
return do_div_mod(from1, from2, to, 0, scale_incr);
2509
the modulus R in R = M mod N
2515
R = M - k*N, where k is integer
2517
thus, there's no requirement for M or N to be integers
2520
@param from1 dividend
2521
@param from2 divisor
2525
2371
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2528
2374
see do_div_mod()
2377
the modulus R in R = M mod N
2383
R = M - k*N, where k is integer
2385
thus, there's no requirement for M or N to be integers
2531
int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2388
int decimal_mod(decimal_t *from1, decimal_t *from2, decimal_t *to)
2533
2390
return do_div_mod(from1, from2, 0, to, 0);
2536
} /* namespace drizzled */