120
113
#include <algorithm>
122
#include "drizzled/current_session.h"
123
#include "drizzled/error.h"
124
#include "drizzled/field.h"
125
#include "drizzled/internal/my_sys.h"
127
115
using namespace std;
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
119
Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
378
146
999900000, 999990000, 999999000,
379
147
999999900, 999999990 };
382
150
#define sanity(d) assert((d)->len > 0)
384
152
#define sanity(d) assert((d)->len >0 && ((d)->buf[0] | \
385
153
(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)))
156
#define FIX_INTG_FRAC_ERROR(len, intg1, frac1, error) \
159
if (unlikely(intg1+frac1 > (len))) \
161
if (unlikely(intg1 > (len))) \
165
error=E_DEC_OVERFLOW; \
170
error=E_DEC_TRUNCATED; \
177
#define ADD(to, from1, from2, carry) /* assume carry <= 1 */ \
180
dec1 a=(from1)+(from2)+(carry); \
181
assert((carry) <= 1); \
182
if (((carry)= a >= DIG_BASE)) /* no division here! */ \
187
#define ADD2(to, from1, from2, carry) \
190
dec2 a=((dec2)(from1))+(from2)+(carry); \
191
if (((carry)= a >= DIG_BASE)) \
193
if (unlikely(a >= DIG_BASE)) \
201
#define SUB(to, from1, from2, carry) /* to=from1-from2 */ \
204
dec1 a=(from1)-(from2)-(carry); \
205
if (((carry)= a < 0)) \
210
#define SUB2(to, from1, from2, carry) /* to=from1-from2 */ \
213
dec1 a=(from1)-(from2)-(carry); \
214
if (((carry)= a < 0)) \
216
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
225
Swap the contents of two variables.
227
#define swap_variables(TYPE, a, b) \
237
Get maximum value for given precision and scale
241
precision/scale - see decimal_bin_size() below
242
to - decimal where where the result will be stored
459
243
to->buf and to->len must be set.
542
@brief Convert decimal to its printable string representation
328
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
332
from - value to convert
333
to - points to buffer where string representation
335
*to_len - in: size of to buffer
336
out: length of the actually written string
337
fixed_precision - 0 if representation can be variable length and
550
338
fixed_decimals will not be checked in this case.
551
339
Put number as with fixed point position with this
552
340
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
342
fixed_decimals - number digits after point.
343
filler - character to fill gaps in case of fixed_precision > 0
559
@retval E_DEC_TRUNCATED
560
@retval E_DEC_OVERFLOW
346
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
562
int decimal2string(const decimal_t *from, char *to, int *to_len,
349
int decimal2string(decimal_t *from, char *to, int *to_len,
563
350
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'
521
Left shift for alignment of data in buffer
525
dec pointer to decimal number which have to be shifted
526
shift number of decimal digits on which it should be shifted
527
beg/end bounds of decimal digits (see digits_bounds())
530
Result fitting in the buffer should be garanted.
531
'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
745
534
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;
536
dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
537
dec1 *end= dec->buf + ROUND_UP(last) - 1;
749
538
int c_shift= DIG_PER_DEC1 - shift;
750
539
assert(from >= dec->buf);
751
540
assert(end < dec->buf + dec->len);
1176
973
rc = decimal2string(from, strbuf, &len, 0, 0, 0);
1177
974
end= strbuf + len;
1179
*to= internal::my_strtod(strbuf, &end, &error);
976
*to= my_strtod(strbuf, &end, &error);
1181
978
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
982
Convert double to decimal
986
from - value to convert
987
to - result will be stored there
1191
990
E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1194
int double2decimal(const double from, decimal_t *to)
993
int double2decimal(double from, decimal_t *to)
1196
995
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);
997
end= buff + my_gcvt(from, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
1201
998
res= string2decimal(buff, to, &end);
1641
1442
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
1446
Rounds the decimal to "scale" digits
1450
from - decimal to round,
1451
to - result buffer. from==to is allowed
1452
scale - to what position to round. can be negative!
1453
mode - round to nearest even or truncate
1653
1456
scale can be negative !
1654
1457
one TRUNCATED error (line XXX below) isn't treated very logical :(
1657
1460
E_DEC_OK/E_DEC_TRUNCATED
1660
decimal_round(const decimal_t *from, decimal_t *to, int scale,
1464
decimal_round(decimal_t *from, decimal_t *to, int scale,
1661
1465
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 +
1467
int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
1468
frac1=ROUND_UP(from->frac), round_digit= 0,
1469
intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len,
1470
intg1=ROUND_UP(from->intg +
1667
1471
(((intg0 + frac0)>0) && (from->buf[0] == DIG_MAX)));
1668
1472
dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
2077
int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1881
int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
2079
1883
if (likely(from1->sign == from2->sign))
2080
1884
return do_add(from1, from2, to);
2081
1885
return do_sub(from1, from2, to);
2084
int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1888
int decimal_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
2086
1890
if (likely(from1->sign == from2->sign))
2087
1891
return do_sub(from1, from2, to);
2088
1892
return do_add(from1, from2, to);
2091
int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
1895
int decimal_cmp(decimal_t *from1, decimal_t *from2)
2093
1897
if (likely(from1->sign == from2->sign))
2094
1898
return do_sub(from1, from2, 0);
2095
1899
return from1->sign > from2->sign ? -1 : 1;
2098
int decimal_is_zero(const decimal_t *from)
1902
int decimal_is_zero(decimal_t *from)
2100
1904
dec1 *buf1=from->buf,
2101
*end=buf1+round_up(from->intg)+round_up(from->frac);
1905
*end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
2102
1906
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
1913
multiply two decimals
1917
from1, from2 - factors
2116
1921
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW;
2119
1924
in this implementation, with sizeof(dec1)=4 we have DIG_PER_DEC1=9,
2120
1925
and 63-digit number will take only 7 dec1 words (basically a 7-digit
2121
1926
"base 999999999" number). Thus there's no need in fast multiplication
2125
1930
XXX if this library is to be used with huge numbers of thousands of
2126
1931
digits, fast multiplication must be implemented.
2128
int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1933
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),
1935
int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1936
frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1937
intg0=ROUND_UP(from1->intg+from2->intg),
2133
1938
frac0=frac1+frac2, error, i, j, d_to_move;
2134
1939
dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
2135
1940
*start2, *stop2, *stop1, *start0, carry;
2235
2040
naive division algorithm (Knuth's Algorithm D in 4.3.1) -
2236
2041
it's ok for short numbers
2237
2042
also we're using alloca() to allocate a temporary buffer
2240
If this library is to be used with huge numbers of thousands of
2044
XXX if this library is to be used with huge numbers of thousands of
2241
2045
digits, fast division must be implemented and alloca should be
2242
2046
changed to malloc (or at least fallback to malloc if alloca() fails)
2243
2047
but then, decimal_mul() should be rewritten too :(
2245
static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
2049
static int do_div_mod(decimal_t *from1, decimal_t *from2,
2246
2050
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,
2052
int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2053
frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2250
2054
error= 0, i, intg0, frac0, len1, len2, dintg, div_mod=(!mod);
2251
2055
dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1,
2252
2056
*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
2292
division of two decimals
2495
2301
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2498
2304
see do_div_mod()
2501
decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, int scale_incr)
2308
decimal_div(decimal_t *from1, decimal_t *from2, decimal_t *to, int scale_incr)
2503
2310
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
2323
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2528
2326
see do_div_mod()
2329
the modulus R in R = M mod N
2335
R = M - k*N, where k is integer
2337
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)
2340
int decimal_mod(decimal_t *from1, decimal_t *from2, decimal_t *to)
2533
2342
return do_div_mod(from1, from2, 0, to, 0);
2536
} /* namespace drizzled */