97
103
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>
114
#include <drizzled/util/test.h>
101
117
#include <alloca.h>
102
#include <m_string.h>
104
#include <storage/myisam/myisampack.h>
105
#include <mystrings/decimal.h>
107
#include <drizzled/util/test.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))
109
345
Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
110
346
So one variable of type decimal_digit_t is limited:
136
378
999900000, 999990000, 999999000,
137
379
999999900, 999999990 };
140
382
#define sanity(d) assert((d)->len > 0)
142
384
#define sanity(d) assert((d)->len >0 && ((d)->buf[0] | \
143
385
(d)->buf[(d)->len-1] | 1))
146
#define FIX_INTG_FRAC_ERROR(len, intg1, frac1, error) \
149
if (unlikely(intg1+frac1 > (len))) \
151
if (unlikely(intg1 > (len))) \
155
error=E_DEC_OVERFLOW; \
160
error=E_DEC_TRUNCATED; \
167
#define ADD(to, from1, from2, carry) /* assume carry <= 1 */ \
170
dec1 a=(from1)+(from2)+(carry); \
171
assert((carry) <= 1); \
172
if (((carry)= a >= DIG_BASE)) /* no division here! */ \
177
#define ADD2(to, from1, from2, carry) \
180
dec2 a=((dec2)(from1))+(from2)+(carry); \
181
if (((carry)= a >= DIG_BASE)) \
183
if (unlikely(a >= DIG_BASE)) \
191
#define SUB(to, from1, from2, carry) /* to=from1-from2 */ \
194
dec1 a=(from1)-(from2)-(carry); \
195
if (((carry)= a < 0)) \
200
#define SUB2(to, from1, from2, carry) /* to=from1-from2 */ \
203
dec1 a=(from1)-(from2)-(carry); \
204
if (((carry)= a < 0)) \
206
if (unlikely(a < 0)) \
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)))
215
Swap the contents of two variables.
217
#define swap_variables(TYPE, a, b) \
227
Get maximum value for given precision and scale
231
precision/scale - see decimal_bin_size() below
232
to - decimal where where the result will be stored
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
233
459
to->buf and to->len must be set.
318
Convert decimal to its printable string representation
542
@brief Convert decimal to its printable string representation
322
from - value to convert
323
to - points to buffer where string representation
325
*to_len - in: size of to buffer
326
out: length of the actually written string
327
fixed_precision - 0 if representation can be variable length and
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
328
550
fixed_decimals will not be checked in this case.
329
551
Put number as with fixed point position with this
330
552
number of digits (sign counted and decimal point is
332
fixed_decimals - number digits after point.
333
filler - character to fill gaps in case of fixed_precision > 0
554
@param fixed_decimals number digits after point.
555
@param filler character to fill gaps in case of fixed_precision > 0
336
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
559
@retval E_DEC_TRUNCATED
560
@retval E_DEC_OVERFLOW
339
int decimal2string(decimal_t *from, char *to, int *to_len,
562
int decimal2string(const decimal_t *from, char *to, int *to_len,
340
563
int fixed_precision, int fixed_decimals,
511
Left shift for alignment of data in buffer
515
dec pointer to decimal number which have to be shifted
516
shift number of decimal digits on which it should be shifted
517
beg/end bounds of decimal digits (see digits_bounds())
520
Result fitting in the buffer should be garanted.
521
'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
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'
524
745
static void do_mini_left_shift(decimal_t *dec, int shift, int beg, int last)
526
dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
527
dec1 *end= dec->buf + ROUND_UP(last) - 1;
747
dec1 *from= dec->buf + round_up(beg + 1) - 1;
748
dec1 *end= dec->buf + round_up(last) - 1;
528
749
int c_shift= DIG_PER_DEC1 - shift;
529
750
assert(from >= dec->buf);
530
751
assert(end < dec->buf + dec->len);
963
1176
rc = decimal2string(from, strbuf, &len, 0, 0, 0);
964
1177
end= strbuf + len;
966
*to= my_strtod(strbuf, &end, &error);
1179
*to= internal::my_strtod(strbuf, &end, &error);
968
1181
return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
972
Convert double to decimal
976
from - value to convert
977
to - result will be stored there
1185
@param Convert double to decimal
1187
@param[in] from value to convert
1188
@param[out] to result will be stored there
980
1191
E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
983
int double2decimal(double from, decimal_t *to)
1194
int double2decimal(const double from, decimal_t *to)
985
1196
char buff[FLOATING_POINT_BUFFER], *end;
987
end= buff + my_gcvt(from, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
1198
end= buff + internal::my_gcvt(from,
1199
internal::MY_GCVT_ARG_DOUBLE,
1200
sizeof(buff) - 1, buff, NULL);
988
1201
res= string2decimal(buff, to, &end);
1446
1641
frac0*sizeof(dec1)+dig2bytes[frac0x];
1450
Rounds the decimal to "scale" digits
1454
from - decimal to round,
1455
to - result buffer. from==to is allowed
1456
scale - to what position to round. can be negative!
1457
mode - round to nearest even or truncate
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
1460
1653
scale can be negative !
1461
1654
one TRUNCATED error (line XXX below) isn't treated very logical :(
1464
1657
E_DEC_OK/E_DEC_TRUNCATED
1468
decimal_round(decimal_t *from, decimal_t *to, int scale,
1660
decimal_round(const decimal_t *from, decimal_t *to, int scale,
1469
1661
decimal_round_mode mode)
1471
int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
1472
frac1=ROUND_UP(from->frac), round_digit= 0,
1473
intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len,
1474
intg1=ROUND_UP(from->intg +
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 +
1475
1667
(((intg0 + frac0)>0) && (from->buf[0] == DIG_MAX)));
1476
1668
dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
1661
Returns the size of the result of the operation
1664
decimal_result_size()
1665
from1 - operand of the unary operation or first operand of the
1667
from2 - second operand of the binary operation
1668
op - operation. one char '+', '-', '*', '/' are allowed
1669
others may be added later
1670
param - extra param to the operation. unused for '+', '-', '*'
1671
scale increment for '/'
1674
returned valued may be larger than the actual buffer requred
1675
in the operation, as decimal_result_size, by design, operates on
1676
precision/scale values only and not on the actual decimal number
1679
size of to->buf array in dec1 elements. to get size in bytes
1680
multiply by sizeof(dec1)
1683
int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, int param)
1687
return ROUND_UP(cmax(from1->intg, from2->intg)) +
1688
ROUND_UP(cmax(from1->frac, from2->frac));
1690
return ROUND_UP(cmax(from1->intg, from2->intg)+1) +
1691
ROUND_UP(cmax(from1->frac, from2->frac));
1693
return ROUND_UP(from1->intg+from2->intg)+
1694
ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
1696
return ROUND_UP(from1->intg+from2->intg+1+from1->frac+from2->frac+param);
1699
return -1; /* shut up the warning */
1702
static int do_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
1704
int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1705
frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1706
frac0=cmax(frac1, frac2), intg0=cmax(intg1, intg2), error;
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;
1707
1857
dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
1927
int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
2077
int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1929
2079
if (likely(from1->sign == from2->sign))
1930
2080
return do_add(from1, from2, to);
1931
2081
return do_sub(from1, from2, to);
1934
int decimal_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
2084
int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1936
2086
if (likely(from1->sign == from2->sign))
1937
2087
return do_sub(from1, from2, to);
1938
2088
return do_add(from1, from2, to);
1941
int decimal_cmp(decimal_t *from1, decimal_t *from2)
2091
int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
1943
2093
if (likely(from1->sign == from2->sign))
1944
2094
return do_sub(from1, from2, 0);
1945
2095
return from1->sign > from2->sign ? -1 : 1;
1948
int decimal_is_zero(decimal_t *from)
2098
int decimal_is_zero(const decimal_t *from)
1950
2100
dec1 *buf1=from->buf,
1951
*end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
2101
*end=buf1+round_up(from->intg)+round_up(from->frac);
1952
2102
while (buf1 < end)
1959
multiply two decimals
1963
from1, from2 - factors
2109
@brief multiply two decimals
2111
@param[in] from1 First factor
2112
@param[in] from2 Second factor
2113
@param[out] to product
1967
2116
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW;
1970
2119
in this implementation, with sizeof(dec1)=4 we have DIG_PER_DEC1=9,
1971
2120
and 63-digit number will take only 7 dec1 words (basically a 7-digit
1972
2121
"base 999999999" number). Thus there's no need in fast multiplication
1976
2125
XXX if this library is to be used with huge numbers of thousands of
1977
2126
digits, fast multiplication must be implemented.
1979
int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to)
2128
int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1981
int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1982
frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1983
intg0=ROUND_UP(from1->intg+from2->intg),
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),
1984
2133
frac0=frac1+frac2, error, i, j, d_to_move;
1985
2134
dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
1986
2135
*start2, *stop2, *stop1, *start0, carry;
2086
2235
naive division algorithm (Knuth's Algorithm D in 4.3.1) -
2087
2236
it's ok for short numbers
2088
2237
also we're using alloca() to allocate a temporary buffer
2090
XXX if this library is to be used with huge numbers of thousands of
2240
If this library is to be used with huge numbers of thousands of
2091
2241
digits, fast division must be implemented and alloca should be
2092
2242
changed to malloc (or at least fallback to malloc if alloca() fails)
2093
2243
but then, decimal_mul() should be rewritten too :(
2095
static int do_div_mod(decimal_t *from1, decimal_t *from2,
2245
static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
2096
2246
decimal_t *to, decimal_t *mod, int scale_incr)
2098
int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2099
frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
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
2250
error= 0, i, intg0, frac0, len1, len2, dintg, div_mod=(!mod);
2101
2251
dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1,
2102
2252
*start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry;
2338
division of two decimals
2488
@brief division of two decimals
2490
@param[in] from1 dividend
2491
@param[in] from2 divisor
2492
@param[out] to quotient
2347
2495
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2350
2498
see do_div_mod()
2354
decimal_div(decimal_t *from1, decimal_t *from2, decimal_t *to, int scale_incr)
2501
decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, int scale_incr)
2356
2503
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
2369
2525
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2372
2528
see do_div_mod()
2375
the modulus R in R = M mod N
2381
R = M - k*N, where k is integer
2383
thus, there's no requirement for M or N to be integers
2386
int decimal_mod(decimal_t *from1, decimal_t *from2, decimal_t *to)
2531
int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2388
2533
return do_div_mod(from1, from2, 0, to, 0);
2536
} /* namespace drizzled */