1/* Copyright (c) 2004, 2014, Oracle and/or its affiliates.
2 Copyright (c) 2009, 2014, Monty Program Ab.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16
17/*
18=======================================================================
19 NOTE: this library implements SQL standard "exact numeric" type
20 and is not at all generic, but rather intentinally crippled to
21 follow the standard :)
22=======================================================================
23 Quoting the standard
24 (SQL:2003, Part 2 Foundations, aka ISO/IEC 9075-2:2003)
25
264.4.2 Characteristics of numbers, page 27:
27
28 An exact numeric type has a precision P and a scale S. P is a positive
29 integer that determines the number of significant digits in a
30 particular radix R, where R is either 2 or 10. S is a non-negative
31 integer. Every value of an exact numeric type of scale S is of the
32 form n*10^{-S}, where n is an integer such that -R^P <= n <= R^P.
33
34 [...]
35
36 If an assignment of some number would result in a loss of its most
37 significant digit, an exception condition is raised. If least
38 significant digits are lost, implementation-defined rounding or
39 truncating occurs, with no exception condition being raised.
40
41 [...]
42
43 Whenever an exact or approximate numeric value is assigned to an exact
44 numeric value site, an approximation of its value that preserves
45 leading significant digits after rounding or truncating is represented
46 in the declared type of the target. The value is converted to have the
47 precision and scale of the target. The choice of whether to truncate
48 or round is implementation-defined.
49
50 [...]
51
52 All numeric values between the smallest and the largest value,
53 inclusive, in a given exact numeric type have an approximation
54 obtained by rounding or truncation for that type; it is
55 implementation-defined which other numeric values have such
56 approximations.
57
585.3 <literal>, page 143
59
60 <exact numeric literal> ::=
61 <unsigned integer> [ <period> [ <unsigned integer> ] ]
62 | <period> <unsigned integer>
63
646.1 <data type>, page 165:
65
66 19) The <scale> of an <exact numeric type> shall not be greater than
67 the <precision> of the <exact numeric type>.
68
69 20) For the <exact numeric type>s DECIMAL and NUMERIC:
70
71 a) The maximum value of <precision> is implementation-defined.
72 <precision> shall not be greater than this value.
73 b) The maximum value of <scale> is implementation-defined. <scale>
74 shall not be greater than this maximum value.
75
76 21) NUMERIC specifies the data type exact numeric, with the decimal
77 precision and scale specified by the <precision> and <scale>.
78
79 22) DECIMAL specifies the data type exact numeric, with the decimal
80 scale specified by the <scale> and the implementation-defined
81 decimal precision equal to or greater than the value of the
82 specified <precision>.
83
846.26 <numeric value expression>, page 241:
85
86 1) If the declared type of both operands of a dyadic arithmetic
87 operator is exact numeric, then the declared type of the result is
88 an implementation-defined exact numeric type, with precision and
89 scale determined as follows:
90
91 a) Let S1 and S2 be the scale of the first and second operands
92 respectively.
93 b) The precision of the result of addition and subtraction is
94 implementation-defined, and the scale is the maximum of S1 and S2.
95 c) The precision of the result of multiplication is
96 implementation-defined, and the scale is S1 + S2.
97 d) The precision and scale of the result of division are
98 implementation-defined.
99*/
100
101#include "strings_def.h"
102#include <m_ctype.h>
103#include <myisampack.h>
104#include <my_sys.h> /* for my_alloca */
105#include <decimal.h>
106
107/*
108 Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
109 So one variable of type decimal_digit_t is limited:
110
111 0 < decimal_digit <= DIG_MAX < DIG_BASE
112
113 in the struct st_decimal_t:
114
115 intg is the number of *decimal* digits (NOT number of decimal_digit_t's !)
116 before the point
117 frac - number of decimal digits after the point
118 buf is an array of decimal_digit_t's
119 len is the length of buf (length of allocated space) in decimal_digit_t's,
120 not in bytes
121*/
122typedef decimal_digit_t dec1;
123typedef longlong dec2;
124
125#define DIG_PER_DEC1 9
126#define DIG_MASK 100000000
127#define DIG_BASE 1000000000
128#define DIG_MAX (DIG_BASE-1)
129#define DIG_BASE2 ((dec2)DIG_BASE * (dec2)DIG_BASE)
130static const dec1 powers10[DIG_PER_DEC1+1]={
131 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
132static const int dig2bytes[DIG_PER_DEC1+1]={0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
133static const dec1 frac_max[DIG_PER_DEC1-1]={
134 900000000, 990000000, 999000000,
135 999900000, 999990000, 999999000,
136 999999900, 999999990 };
137
138static inline int ROUND_UP(int x)
139{
140 return (x + (x > 0 ? DIG_PER_DEC1 - 1 : 0)) / DIG_PER_DEC1;
141}
142
143#ifdef HAVE_valgrind
144#define sanity(d) DBUG_ASSERT((d)->len > 0)
145#else
146#define sanity(d) DBUG_ASSERT((d)->len >0 && ((d)->buf[0] | \
147 (d)->buf[(d)->len-1] | 1))
148#endif
149
150#define FIX_INTG_FRAC_ERROR(len, intg1, frac1, error) \
151 do \
152 { \
153 if (unlikely(intg1+frac1 > (len))) \
154 { \
155 if (unlikely(intg1 > (len))) \
156 { \
157 intg1=(len); \
158 frac1=0; \
159 error=E_DEC_OVERFLOW; \
160 } \
161 else \
162 { \
163 frac1=(len)-intg1; \
164 error=E_DEC_TRUNCATED; \
165 } \
166 } \
167 else \
168 error=E_DEC_OK; \
169 } while(0)
170
171#define ADD(to, from1, from2, carry) /* assume carry <= 1 */ \
172 do \
173 { \
174 dec1 a=(from1)+(from2)+(carry); \
175 DBUG_ASSERT((carry) <= 1); \
176 if (((carry)= a >= DIG_BASE)) /* no division here! */ \
177 a-=DIG_BASE; \
178 (to)=a; \
179 } while(0)
180
181#define ADD2(to, from1, from2, carry) \
182 do \
183 { \
184 dec2 a=((dec2)(from1))+(from2)+(carry); \
185 if (((carry)= a >= DIG_BASE)) \
186 a-=DIG_BASE; \
187 if (unlikely(a >= DIG_BASE)) \
188 { \
189 a-=DIG_BASE; \
190 carry++; \
191 } \
192 (to)=(dec1) a; \
193 } while(0)
194
195#define SUB(to, from1, from2, carry) /* to=from1-from2 */ \
196 do \
197 { \
198 dec1 a=(from1)-(from2)-(carry); \
199 if (((carry)= a < 0)) \
200 a+=DIG_BASE; \
201 (to)=a; \
202 } while(0)
203
204#define SUB2(to, from1, from2, carry) /* to=from1-from2 */ \
205 do \
206 { \
207 dec1 a=(from1)-(from2)-(carry); \
208 if (((carry)= a < 0)) \
209 a+=DIG_BASE; \
210 if (unlikely(a < 0)) \
211 { \
212 a+=DIG_BASE; \
213 carry++; \
214 } \
215 (to)=a; \
216 } while(0)
217
218/*
219 Get maximum value for given precision and scale
220
221 SYNOPSIS
222 max_decimal()
223 precision/scale - see decimal_bin_size() below
224 to - decimal where where the result will be stored
225 to->buf and to->len must be set.
226*/
227
228void max_decimal(int precision, int frac, decimal_t *to)
229{
230 int intpart;
231 dec1 *buf= to->buf;
232 DBUG_ASSERT(precision && precision >= frac);
233
234 to->sign= 0;
235 if ((intpart= to->intg= (precision - frac)))
236 {
237 int firstdigits= intpart % DIG_PER_DEC1;
238 if (firstdigits)
239 *buf++= powers10[firstdigits] - 1; /* get 9 99 999 ... */
240 for(intpart/= DIG_PER_DEC1; intpart; intpart--)
241 *buf++= DIG_MAX;
242 }
243
244 if ((to->frac= frac))
245 {
246 int lastdigits= frac % DIG_PER_DEC1;
247 for(frac/= DIG_PER_DEC1; frac; frac--)
248 *buf++= DIG_MAX;
249 if (lastdigits)
250 *buf= frac_max[lastdigits - 1];
251 }
252}
253
254
255static dec1 *remove_leading_zeroes(const decimal_t *from, int *intg_result)
256{
257 int intg= from->intg, i;
258 dec1 *buf0= from->buf;
259 i= ((intg - 1) % DIG_PER_DEC1) + 1;
260 while (intg > 0 && *buf0 == 0)
261 {
262 intg-= i;
263 i= DIG_PER_DEC1;
264 buf0++;
265 }
266 if (intg > 0)
267 {
268 for (i= (intg - 1) % DIG_PER_DEC1; *buf0 < powers10[i--]; intg--) ;
269 DBUG_ASSERT(intg > 0);
270 }
271 else
272 intg=0;
273 *intg_result= intg;
274 return buf0;
275}
276
277
278/*
279 Count actual length of fraction part (without ending zeroes)
280
281 SYNOPSIS
282 decimal_actual_fraction()
283 from number for processing
284*/
285
286int decimal_actual_fraction(const decimal_t *from)
287{
288 int frac= from->frac, i;
289 dec1 *buf0= from->buf + ROUND_UP(from->intg) + ROUND_UP(frac) - 1;
290
291 if (frac == 0)
292 return 0;
293
294 i= ((frac - 1) % DIG_PER_DEC1 + 1);
295 while (frac > 0 && *buf0 == 0)
296 {
297 frac-= i;
298 i= DIG_PER_DEC1;
299 buf0--;
300 }
301 if (frac > 0)
302 {
303 for (i= DIG_PER_DEC1 - ((frac - 1) % DIG_PER_DEC1);
304 *buf0 % powers10[i++] == 0;
305 frac--) {}
306 }
307 return frac;
308}
309
310
311/*
312 Convert decimal to its printable string representation
313
314 SYNOPSIS
315 decimal2string()
316 from - value to convert
317 to - points to buffer where string representation
318 should be stored
319 *to_len - in: size of to buffer (incl. terminating '\0')
320 out: length of the actually written string (excl. '\0')
321 fixed_precision - 0 if representation can be variable length and
322 fixed_decimals will not be checked in this case.
323 Put number as with fixed point position with this
324 number of digits (sign counted and decimal point is
325 counted)
326 fixed_decimals - number digits after point.
327 filler - character to fill gaps in case of fixed_precision > 0
328
329 RETURN VALUE
330 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
331*/
332
333int decimal2string(const decimal_t *from, char *to, int *to_len,
334 int fixed_precision, int fixed_decimals,
335 char filler)
336{
337 /* {intg_len, frac_len} output widths; {intg, frac} places in input */
338 int len, intg, frac= from->frac, i, intg_len, frac_len, fill;
339 /* number digits before decimal point */
340 int fixed_intg= (fixed_precision ?
341 (fixed_precision - fixed_decimals) : 0);
342 int error=E_DEC_OK;
343 char *s=to;
344 dec1 *buf, *buf0=from->buf, tmp;
345
346 DBUG_ASSERT(*to_len >= 2+ (int) from->sign);
347
348 /* removing leading zeroes */
349 buf0= remove_leading_zeroes(from, &intg);
350 if (unlikely(intg+frac==0))
351 {
352 intg=1;
353 tmp=0;
354 buf0=&tmp;
355 }
356
357 if (!(intg_len= fixed_precision ? fixed_intg : intg))
358 intg_len= 1;
359 frac_len= fixed_precision ? fixed_decimals : frac;
360 len= from->sign + intg_len + MY_TEST(frac) + frac_len;
361 if (fixed_precision)
362 {
363 if (frac > fixed_decimals)
364 {
365 error= E_DEC_TRUNCATED;
366 frac= fixed_decimals;
367 }
368 if (intg > fixed_intg)
369 {
370 error= E_DEC_OVERFLOW;
371 intg= fixed_intg;
372 }
373 }
374 else if (unlikely(len > --*to_len)) /* reserve one byte for \0 */
375 {
376 int j= len-*to_len;
377 error= (frac && j <= frac + 1) ? E_DEC_TRUNCATED : E_DEC_OVERFLOW;
378 if (frac && j >= frac + 1) j--;
379 if (j > frac)
380 {
381 intg-= j-frac;
382 frac= 0;
383 }
384 else
385 frac-=j;
386 frac_len= frac;
387 len= from->sign + intg_len + MY_TEST(frac) + frac_len;
388 }
389 *to_len=len;
390 s[len]=0;
391
392 if (from->sign)
393 *s++='-';
394
395 if (frac)
396 {
397 char *s1= s + intg_len;
398 fill= frac_len - frac;
399 buf=buf0+ROUND_UP(intg);
400 *s1++='.';
401 for (; frac>0; frac-=DIG_PER_DEC1)
402 {
403 dec1 x=*buf++;
404 for (i=MY_MIN(frac, DIG_PER_DEC1); i; i--)
405 {
406 dec1 y=x/DIG_MASK;
407 *s1++='0'+(uchar)y;
408 x-=y*DIG_MASK;
409 x*=10;
410 }
411 }
412 for(; fill; fill--)
413 *s1++=filler;
414 }
415
416 fill= intg_len - intg;
417 if (intg == 0)
418 fill--; /* symbol 0 before digital point */
419 for(; fill; fill--)
420 *s++=filler;
421 if (intg)
422 {
423 s+=intg;
424 for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
425 {
426 dec1 x=*--buf;
427 for (i=MY_MIN(intg, DIG_PER_DEC1); i; i--)
428 {
429 dec1 y=x/10;
430 *--s='0'+(uchar)(x-y*10);
431 x=y;
432 }
433 }
434 }
435 else
436 *s= '0';
437 return error;
438}
439
440
441/*
442 Return bounds of decimal digits in the number
443
444 SYNOPSIS
445 digits_bounds()
446 from - decimal number for processing
447 start_result - index (from 0 ) of first decimal digits will
448 be written by this address
449 end_result - index of position just after last decimal digit
450 be written by this address
451*/
452
453static void digits_bounds(decimal_t *from, int *start_result, int *end_result)
454{
455 int start, stop, i;
456 dec1 *buf_beg= from->buf;
457 dec1 *end= from->buf + ROUND_UP(from->intg) + ROUND_UP(from->frac);
458 dec1 *buf_end= end - 1;
459
460 /* find non-zero digit from number beginning */
461 while (buf_beg < end && *buf_beg == 0)
462 buf_beg++;
463
464 if (buf_beg >= end)
465 {
466 /* it is zero */
467 *start_result= *end_result= 0;
468 return;
469 }
470
471 /* find non-zero decimal digit from number beginning */
472 if (buf_beg == from->buf && from->intg)
473 {
474 start= DIG_PER_DEC1 - (i= ((from->intg-1) % DIG_PER_DEC1 + 1));
475 i--;
476 }
477 else
478 {
479 i= DIG_PER_DEC1 - 1;
480 start= (int) ((buf_beg - from->buf) * DIG_PER_DEC1);
481 }
482 if (buf_beg < end)
483 for (; *buf_beg < powers10[i--]; start++) ;
484 *start_result= start; /* index of first decimal digit (from 0) */
485
486 /* find non-zero digit at the end */
487 while (buf_end > buf_beg && *buf_end == 0)
488 buf_end--;
489 /* find non-zero decimal digit from the end */
490 if (buf_end == end - 1 && from->frac)
491 {
492 stop= (int) (((buf_end - from->buf) * DIG_PER_DEC1 +
493 (i= ((from->frac - 1) % DIG_PER_DEC1 + 1))));
494 i= DIG_PER_DEC1 - i + 1;
495 }
496 else
497 {
498 stop= (int) ((buf_end - from->buf + 1) * DIG_PER_DEC1);
499 i= 1;
500 }
501 for (; *buf_end % powers10[i++] == 0; stop--) {}
502 *end_result= stop; /* index of position after last decimal digit (from 0) */
503}
504
505
506/*
507 Left shift for alignment of data in buffer
508
509 SYNOPSIS
510 do_mini_left_shift()
511 dec pointer to decimal number which have to be shifted
512 shift number of decimal digits on which it should be shifted
513 beg/end bounds of decimal digits (see digits_bounds())
514
515 NOTE
516 Result fitting in the buffer should be garanted.
517 'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
518*/
519
520void do_mini_left_shift(decimal_t *dec, int shift, int beg, int last)
521{
522 dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
523 dec1 *end= dec->buf + ROUND_UP(last) - 1;
524 int c_shift= DIG_PER_DEC1 - shift;
525 DBUG_ASSERT(from >= dec->buf);
526 DBUG_ASSERT(end < dec->buf + dec->len);
527 if (beg % DIG_PER_DEC1 < shift)
528 *(from - 1)= (*from) / powers10[c_shift];
529 for(; from < end; from++)
530 *from= ((*from % powers10[c_shift]) * powers10[shift] +
531 (*(from + 1)) / powers10[c_shift]);
532 *from= (*from % powers10[c_shift]) * powers10[shift];
533}
534
535
536/*
537 Right shift for alignment of data in buffer
538
539 SYNOPSIS
540 do_mini_left_shift()
541 dec pointer to decimal number which have to be shifted
542 shift number of decimal digits on which it should be shifted
543 beg/end bounds of decimal digits (see digits_bounds())
544
545 NOTE
546 Result fitting in the buffer should be garanted.
547 'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
548*/
549
550void do_mini_right_shift(decimal_t *dec, int shift, int beg, int last)
551{
552 dec1 *from= dec->buf + ROUND_UP(last) - 1;
553 dec1 *end= dec->buf + ROUND_UP(beg + 1) - 1;
554 int c_shift= DIG_PER_DEC1 - shift;
555 DBUG_ASSERT(from < dec->buf + dec->len);
556 DBUG_ASSERT(end >= dec->buf);
557 if (DIG_PER_DEC1 - ((last - 1) % DIG_PER_DEC1 + 1) < shift)
558 *(from + 1)= (*from % powers10[shift]) * powers10[c_shift];
559 for(; from > end; from--)
560 *from= (*from / powers10[shift] +
561 (*(from - 1) % powers10[shift]) * powers10[c_shift]);
562 *from= *from / powers10[shift];
563}
564
565
566/*
567 Shift of decimal digits in given number (with rounding if it need)
568
569 SYNOPSIS
570 decimal_shift()
571 dec number to be shifted
572 shift number of decimal positions
573 shift > 0 means shift to left shift
574 shift < 0 meand right shift
575 NOTE
576 In fact it is multipling on 10^shift.
577 RETURN
578 E_DEC_OK OK
579 E_DEC_OVERFLOW operation lead to overflow, number is untoched
580 E_DEC_TRUNCATED number was rounded to fit into buffer
581*/
582
583int decimal_shift(decimal_t *dec, int shift)
584{
585 /* index of first non zero digit (all indexes from 0) */
586 int beg;
587 /* index of position after last decimal digit */
588 int end;
589 /* index of digit position just after point */
590 int point= ROUND_UP(dec->intg) * DIG_PER_DEC1;
591 /* new point position */
592 int new_point= point + shift;
593 /* number of digits in result */
594 int digits_int, digits_frac;
595 /* length of result and new fraction in big digits*/
596 int new_len, new_frac_len;
597 /* return code */
598 int err= E_DEC_OK;
599 int new_front;
600
601 if (shift == 0)
602 return E_DEC_OK;
603
604 digits_bounds(dec, &beg, &end);
605
606 if (beg == end)
607 {
608 decimal_make_zero(dec);
609 return E_DEC_OK;
610 }
611
612 digits_int= new_point - beg;
613 set_if_bigger(digits_int, 0);
614 digits_frac= end - new_point;
615 set_if_bigger(digits_frac, 0);
616
617 if ((new_len= ROUND_UP(digits_int) + (new_frac_len= ROUND_UP(digits_frac))) >
618 dec->len)
619 {
620 int lack= new_len - dec->len;
621 int diff;
622
623 if (new_frac_len < lack)
624 return E_DEC_OVERFLOW; /* lack more then we have in fraction */
625
626 /* cat off fraction part to allow new number to fit in our buffer */
627 err= E_DEC_TRUNCATED;
628 new_frac_len-= lack;
629 diff= digits_frac - (new_frac_len * DIG_PER_DEC1);
630 /* Make rounding method as parameter? */
631 decimal_round(dec, dec, end - point - diff, HALF_UP);
632 end-= diff;
633 digits_frac= new_frac_len * DIG_PER_DEC1;
634
635 if (end <= beg)
636 {
637 /*
638 we lost all digits (they will be shifted out of buffer), so we can
639 just return 0
640 */
641 decimal_make_zero(dec);
642 return E_DEC_TRUNCATED;
643 }
644 }
645
646 if (shift % DIG_PER_DEC1)
647 {
648 int l_mini_shift, r_mini_shift, mini_shift;
649 int do_left;
650 /*
651 Calculate left/right shift to align decimal digits inside our bug
652 digits correctly
653 */
654 if (shift > 0)
655 {
656 l_mini_shift= shift % DIG_PER_DEC1;
657 r_mini_shift= DIG_PER_DEC1 - l_mini_shift;
658 /*
659 It is left shift so prefer left shift, but if we have not place from
660 left, we have to have it from right, because we checked length of
661 result
662 */
663 do_left= l_mini_shift <= beg;
664 DBUG_ASSERT(do_left || (dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
665 }
666 else
667 {
668 r_mini_shift= (-shift) % DIG_PER_DEC1;
669 l_mini_shift= DIG_PER_DEC1 - r_mini_shift;
670 /* see comment above */
671 do_left= !((dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
672 DBUG_ASSERT(!do_left || l_mini_shift <= beg);
673 }
674 if (do_left)
675 {
676 do_mini_left_shift(dec, l_mini_shift, beg, end);
677 mini_shift= -l_mini_shift;
678 }
679 else
680 {
681 do_mini_right_shift(dec, r_mini_shift, beg, end);
682 mini_shift= r_mini_shift;
683 }
684 new_point+= mini_shift;
685 /*
686 If number is shifted and correctly aligned in buffer we can
687 finish
688 */
689 if (!(shift+= mini_shift) && (new_point - digits_int) < DIG_PER_DEC1)
690 {
691 dec->intg= digits_int;
692 dec->frac= digits_frac;
693 return err; /* already shifted as it should be */
694 }
695 beg+= mini_shift;
696 end+= mini_shift;
697 }
698
699 /* if new 'decimal front' is in first digit, we do not need move digits */
700 if ((new_front= (new_point - digits_int)) >= DIG_PER_DEC1 ||
701 new_front < 0)
702 {
703 /* need to move digits */
704 int d_shift;
705 dec1 *to, *barier;
706 if (new_front > 0)
707 {
708 /* move left */
709 d_shift= new_front / DIG_PER_DEC1;
710 to= dec->buf + (ROUND_UP(beg + 1) - 1 - d_shift);
711 barier= dec->buf + (ROUND_UP(end) - 1 - d_shift);
712 DBUG_ASSERT(to >= dec->buf);
713 DBUG_ASSERT(barier + d_shift < dec->buf + dec->len);
714 for(; to <= barier; to++)
715 *to= *(to + d_shift);
716 for(barier+= d_shift; to <= barier; to++)
717 *to= 0;
718 d_shift= -d_shift;
719 }
720 else
721 {
722 /* move right */
723 d_shift= (1 - new_front) / DIG_PER_DEC1;
724 to= dec->buf + ROUND_UP(end) - 1 + d_shift;
725 barier= dec->buf + ROUND_UP(beg + 1) - 1 + d_shift;
726 DBUG_ASSERT(to < dec->buf + dec->len);
727 DBUG_ASSERT(barier - d_shift >= dec->buf);
728 for(; to >= barier; to--)
729 *to= *(to - d_shift);
730 for(barier-= d_shift; to >= barier; to--)
731 *to= 0;
732 }
733 d_shift*= DIG_PER_DEC1;
734 beg+= d_shift;
735 end+= d_shift;
736 new_point+= d_shift;
737 }
738
739 /*
740 If there are gaps then fill ren with 0.
741
742 Only one of following 'for' loops will work because beg <= end
743 */
744 beg= ROUND_UP(beg + 1) - 1;
745 end= ROUND_UP(end) - 1;
746 DBUG_ASSERT(new_point >= 0);
747
748 /* We don't want negative new_point below */
749 if (new_point != 0)
750 new_point= ROUND_UP(new_point) - 1;
751
752 if (new_point > end)
753 {
754 do
755 {
756 dec->buf[new_point]=0;
757 } while (--new_point > end);
758 }
759 else
760 {
761 for (; new_point < beg; new_point++)
762 dec->buf[new_point]= 0;
763 }
764 dec->intg= digits_int;
765 dec->frac= digits_frac;
766 return err;
767}
768
769
770/*
771 Convert string to decimal
772
773 SYNOPSIS
774 internal_str2decl()
775 from - value to convert. Doesn't have to be \0 terminated!
776 to - decimal where where the result will be stored
777 to->buf and to->len must be set.
778 end - Pointer to pointer to end of string. Will on return be
779 set to the char after the last used character
780 fixed - use to->intg, to->frac as limits for input number
781
782 NOTE
783 to->intg and to->frac can be modified even when fixed=1
784 (but only decreased, in this case)
785
786 RETURN VALUE
787 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_BAD_NUM/E_DEC_OOM
788 In case of E_DEC_FATAL_ERROR *to is set to decimal zero
789 (to make error handling easier)
790*/
791
792int
793internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed)
794{
795 const char *s= from, *s1, *endp, *end_of_string= *end;
796 int i, intg, frac, error, intg1, frac1;
797 dec1 x,*buf;
798 sanity(to);
799
800 error= E_DEC_BAD_NUM; /* In case of bad number */
801 while (s < end_of_string && my_isspace(&my_charset_latin1, *s))
802 s++;
803 if (s == end_of_string)
804 goto fatal_error;
805
806 if ((to->sign= (*s == '-')))
807 s++;
808 else if (*s == '+')
809 s++;
810
811 s1=s;
812 while (s < end_of_string && my_isdigit(&my_charset_latin1, *s))
813 s++;
814 intg= (int) (s-s1);
815 if (s < end_of_string && *s=='.')
816 {
817 endp= s+1;
818 while (endp < end_of_string && my_isdigit(&my_charset_latin1, *endp))
819 endp++;
820 frac= (int) (endp - s - 1);
821 }
822 else
823 {
824 frac= 0;
825 endp= s;
826 }
827
828 *end= (char*) endp;
829
830 if (frac+intg == 0)
831 goto fatal_error;
832
833 error= 0;
834 if (fixed)
835 {
836 if (frac > to->frac)
837 {
838 error=E_DEC_TRUNCATED;
839 frac=to->frac;
840 }
841 if (intg > to->intg)
842 {
843 error=E_DEC_OVERFLOW;
844 intg=to->intg;
845 }
846 intg1=ROUND_UP(intg);
847 frac1=ROUND_UP(frac);
848 if (intg1+frac1 > to->len)
849 {
850 error= E_DEC_OOM;
851 goto fatal_error;
852 }
853 }
854 else
855 {
856 intg1=ROUND_UP(intg);
857 frac1=ROUND_UP(frac);
858 FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
859 if (unlikely(error))
860 {
861 frac=frac1*DIG_PER_DEC1;
862 if (error == E_DEC_OVERFLOW)
863 intg=intg1*DIG_PER_DEC1;
864 }
865 }
866 /* Error is guaranteed to be set here */
867 to->intg=intg;
868 to->frac=frac;
869
870 buf=to->buf+intg1;
871 s1=s;
872
873 for (x=0, i=0; intg; intg--)
874 {
875 x+= (*--s - '0')*powers10[i];
876
877 if (unlikely(++i == DIG_PER_DEC1))
878 {
879 *--buf=x;
880 x=0;
881 i=0;
882 }
883 }
884 if (i)
885 *--buf=x;
886
887 buf=to->buf+intg1;
888 for (x=0, i=0; frac; frac--)
889 {
890 x= (*++s1 - '0') + x*10;
891
892 if (unlikely(++i == DIG_PER_DEC1))
893 {
894 *buf++=x;
895 x=0;
896 i=0;
897 }
898 }
899 if (i)
900 *buf=x*powers10[DIG_PER_DEC1-i];
901
902 /* Handle exponent */
903 if (endp+1 < end_of_string && (*endp == 'e' || *endp == 'E'))
904 {
905 int str_error;
906 longlong exponent= my_strtoll10(endp+1, (char**) &end_of_string,
907 &str_error);
908
909 if (end_of_string != endp +1) /* If at least one digit */
910 {
911 *end= (char*) end_of_string;
912 if (str_error > 0)
913 {
914 error= E_DEC_BAD_NUM;
915 goto fatal_error;
916 }
917 if (exponent > INT_MAX/2 || (str_error == 0 && exponent < 0))
918 {
919 error= E_DEC_OVERFLOW;
920 goto fatal_error;
921 }
922 if (exponent < INT_MIN/2 && error != E_DEC_OVERFLOW)
923 {
924 error= E_DEC_TRUNCATED;
925 goto fatal_error;
926 }
927 if (error != E_DEC_OVERFLOW)
928 error= decimal_shift(to, (int) exponent);
929 }
930 }
931 if (to->sign && decimal_is_zero(to))
932 to->sign= 0;
933 return error;
934
935fatal_error:
936 decimal_make_zero(to);
937 return error;
938}
939
940
941/*
942 Convert decimal to double
943
944 SYNOPSIS
945 decimal2double()
946 from - value to convert
947 to - result will be stored there
948
949 RETURN VALUE
950 E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
951*/
952
953int decimal2double(const decimal_t *from, double *to)
954{
955 char strbuf[FLOATING_POINT_BUFFER], *end;
956 int len= sizeof(strbuf);
957 int rc, error;
958
959 rc = decimal2string(from, strbuf, &len, 0, 0, 0);
960 end= strbuf + len;
961
962 DBUG_PRINT("info", ("interm.: %s", strbuf));
963
964 *to= my_strtod(strbuf, &end, &error);
965
966 DBUG_PRINT("info", ("result: %f", *to));
967
968 return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
969}
970
971/*
972 Convert double to decimal
973
974 SYNOPSIS
975 double2decimal()
976 from - value to convert
977 to - result will be stored there
978
979 RETURN VALUE
980 E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
981*/
982
983int double2decimal(double from, decimal_t *to)
984{
985 char buff[FLOATING_POINT_BUFFER], *end;
986 int res;
987 DBUG_ENTER("double2decimal");
988 end= buff + my_gcvt(from, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
989 res= string2decimal(buff, to, &end);
990 DBUG_PRINT("exit", ("res: %d", res));
991 DBUG_RETURN(res);
992}
993
994
995static int ull2dec(ulonglong from, decimal_t *to)
996{
997 int intg1, error=E_DEC_OK;
998 ulonglong x=from;
999 dec1 *buf;
1000
1001 sanity(to);
1002
1003 if (!from)
1004 {
1005 decimal_make_zero(to);
1006 return E_DEC_OK;
1007 }
1008
1009 for (intg1=1; from >= DIG_BASE; intg1++, from/=DIG_BASE) {}
1010 if (unlikely(intg1 > to->len))
1011 {
1012 intg1=to->len;
1013 error=E_DEC_OVERFLOW;
1014 }
1015 to->frac=0;
1016 for(to->intg= (intg1-1)*DIG_PER_DEC1; from; to->intg++, from/=10) {}
1017
1018 for (buf=to->buf+intg1; intg1; intg1--)
1019 {
1020 ulonglong y=x/DIG_BASE;
1021 *--buf=(dec1)(x-y*DIG_BASE);
1022 x=y;
1023 }
1024 return error;
1025}
1026
1027int ulonglong2decimal(ulonglong from, decimal_t *to)
1028{
1029 to->sign=0;
1030 return ull2dec(from, to);
1031}
1032
1033int longlong2decimal(longlong from, decimal_t *to)
1034{
1035 if ((to->sign= from < 0))
1036 {
1037 if (from == LONGLONG_MIN) // avoid undefined behavior
1038 return ull2dec((ulonglong)LONGLONG_MIN, to);
1039 return ull2dec(-from, to);
1040 }
1041 return ull2dec(from, to);
1042}
1043
1044int decimal2ulonglong(const decimal_t *from, ulonglong *to)
1045{
1046 dec1 *buf=from->buf;
1047 ulonglong x=0;
1048 int intg, frac;
1049
1050 if (from->sign)
1051 {
1052 *to= 0;
1053 return E_DEC_OVERFLOW;
1054 }
1055
1056 for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1057 {
1058 ulonglong y=x;
1059 x=x*DIG_BASE + *buf++;
1060 if (unlikely(y > ((ulonglong) ULONGLONG_MAX/DIG_BASE) || x < y))
1061 {
1062 *to=ULONGLONG_MAX;
1063 return E_DEC_OVERFLOW;
1064 }
1065 }
1066 *to=x;
1067 for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1068 if (*buf++)
1069 return E_DEC_TRUNCATED;
1070 return E_DEC_OK;
1071}
1072
1073int decimal2longlong(const decimal_t *from, longlong *to)
1074{
1075 dec1 *buf=from->buf;
1076 longlong x=0;
1077 int intg, frac;
1078
1079 for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1080 {
1081 longlong y=x;
1082 /*
1083 Attention: trick!
1084 we're calculating -|from| instead of |from| here
1085 because |LONGLONG_MIN| > LONGLONG_MAX
1086 so we can convert -9223372036854775808 correctly
1087 */
1088 x=x*DIG_BASE - *buf++;
1089 if (unlikely(y < (LONGLONG_MIN/DIG_BASE) || x > y))
1090 {
1091 /*
1092 the decimal is bigger than any possible integer
1093 return border integer depending on the sign
1094 */
1095 *to= from->sign ? LONGLONG_MIN : LONGLONG_MAX;
1096 return E_DEC_OVERFLOW;
1097 }
1098 }
1099 /* boundary case: 9223372036854775808 */
1100 if (unlikely(from->sign==0 && x == LONGLONG_MIN))
1101 {
1102 *to= LONGLONG_MAX;
1103 return E_DEC_OVERFLOW;
1104 }
1105
1106 *to=from->sign ? x : -x;
1107 for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1108 if (*buf++)
1109 return E_DEC_TRUNCATED;
1110 return E_DEC_OK;
1111}
1112
1113/*
1114 Convert decimal to its binary fixed-length representation
1115 two representations of the same length can be compared with memcmp
1116 with the correct -1/0/+1 result
1117
1118 SYNOPSIS
1119 decimal2bin()
1120 from - value to convert
1121 to - points to buffer where string representation should be stored
1122 precision/scale - see decimal_bin_size() below
1123
1124 NOTE
1125 the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1126
1127 RETURN VALUE
1128 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1129
1130 DESCRIPTION
1131 for storage decimal numbers are converted to the "binary" format.
1132
1133 This format has the following properties:
1134 1. length of the binary representation depends on the {precision, scale}
1135 as provided by the caller and NOT on the intg/frac of the decimal to
1136 convert.
1137 2. binary representations of the same {precision, scale} can be compared
1138 with memcmp - with the same result as decimal_cmp() of the original
1139 decimals (not taking into account possible precision loss during
1140 conversion).
1141
1142 This binary format is as follows:
1143 1. First the number is converted to have a requested precision and scale.
1144 2. Every full DIG_PER_DEC1 digits of intg part are stored in 4 bytes
1145 as is
1146 3. The first intg % DIG_PER_DEC1 digits are stored in the reduced
1147 number of bytes (enough bytes to store this number of digits -
1148 see dig2bytes)
1149 4. same for frac - full decimal_digit_t's are stored as is,
1150 the last frac % DIG_PER_DEC1 digits - in the reduced number of bytes.
1151 5. If the number is negative - every byte is inversed.
1152 5. The very first bit of the resulting byte array is inverted (because
1153 memcmp compares unsigned bytes, see property 2 above)
1154
1155 Example:
1156
1157 1234567890.1234
1158
1159 internally is represented as 3 decimal_digit_t's
1160
1161 1 234567890 123400000
1162
1163 (assuming we want a binary representation with precision=14, scale=4)
1164 in hex it's
1165
1166 00-00-00-01 0D-FB-38-D2 07-5A-EF-40
1167
1168 now, middle decimal_digit_t is full - it stores 9 decimal digits. It goes
1169 into binary representation as is:
1170
1171
1172 ........... 0D-FB-38-D2 ............
1173
1174 First decimal_digit_t has only one decimal digit. We can store one digit in
1175 one byte, no need to waste four:
1176
1177 01 0D-FB-38-D2 ............
1178
1179 now, last digit. It's 123400000. We can store 1234 in two bytes:
1180
1181 01 0D-FB-38-D2 04-D2
1182
1183 So, we've packed 12 bytes number in 7 bytes.
1184 And now we invert the highest bit to get the final result:
1185
1186 81 0D FB 38 D2 04 D2
1187
1188 And for -1234567890.1234 it would be
1189
1190 7E F2 04 C7 2D FB 2D
1191*/
1192int decimal2bin(const decimal_t *from, uchar *to, int precision, int frac)
1193{
1194 dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
1195 int error=E_DEC_OK, intg=precision-frac,
1196 isize1, intg1, intg1x, from_intg,
1197 intg0=intg/DIG_PER_DEC1,
1198 frac0=frac/DIG_PER_DEC1,
1199 intg0x=intg-intg0*DIG_PER_DEC1,
1200 frac0x=frac-frac0*DIG_PER_DEC1,
1201 frac1=from->frac/DIG_PER_DEC1,
1202 frac1x=from->frac-frac1*DIG_PER_DEC1,
1203 isize0=intg0*sizeof(dec1)+dig2bytes[intg0x],
1204 fsize0=frac0*sizeof(dec1)+dig2bytes[frac0x],
1205 fsize1=frac1*sizeof(dec1)+dig2bytes[frac1x];
1206 const int orig_isize0= isize0;
1207 const int orig_fsize0= fsize0;
1208 uchar *orig_to= to;
1209
1210 buf1= remove_leading_zeroes(from, &from_intg);
1211
1212 if (unlikely(from_intg+fsize1==0))
1213 {
1214 mask=0; /* just in case */
1215 intg=1;
1216 buf1=&mask;
1217 }
1218
1219 intg1=from_intg/DIG_PER_DEC1;
1220 intg1x=from_intg-intg1*DIG_PER_DEC1;
1221 isize1=intg1*sizeof(dec1)+dig2bytes[intg1x];
1222
1223 if (intg < from_intg)
1224 {
1225 buf1+=intg1-intg0+(intg1x>0)-(intg0x>0);
1226 intg1=intg0; intg1x=intg0x;
1227 error=E_DEC_OVERFLOW;
1228 }
1229 else if (isize0 > isize1)
1230 {
1231 while (isize0-- > isize1)
1232 *to++= (char)mask;
1233 }
1234 if (fsize0 < fsize1)
1235 {
1236 frac1=frac0; frac1x=frac0x;
1237 error=E_DEC_TRUNCATED;
1238 }
1239 else if (fsize0 > fsize1 && frac1x)
1240 {
1241 if (frac0 == frac1)
1242 {
1243 frac1x=frac0x;
1244 fsize0= fsize1;
1245 }
1246 else
1247 {
1248 frac1++;
1249 frac1x=0;
1250 }
1251 }
1252
1253 /* intg1x part */
1254 if (intg1x)
1255 {
1256 int i=dig2bytes[intg1x];
1257 dec1 x=(*buf1++ % powers10[intg1x]) ^ mask;
1258 switch (i)
1259 {
1260 case 1: mi_int1store(to, x); break;
1261 case 2: mi_int2store(to, x); break;
1262 case 3: mi_int3store(to, x); break;
1263 case 4: mi_int4store(to, x); break;
1264 default: DBUG_ASSERT(0);
1265 }
1266 to+=i;
1267 }
1268
1269 /* intg1+frac1 part */
1270 for (stop1=buf1+intg1+frac1; buf1 < stop1; to+=sizeof(dec1))
1271 {
1272 dec1 x=*buf1++ ^ mask;
1273 DBUG_ASSERT(sizeof(dec1) == 4);
1274 mi_int4store(to, x);
1275 }
1276
1277 /* frac1x part */
1278 if (frac1x)
1279 {
1280 dec1 x;
1281 int i=dig2bytes[frac1x],
1282 lim=(frac1 < frac0 ? DIG_PER_DEC1 : frac0x);
1283 while (frac1x < lim && dig2bytes[frac1x] == i)
1284 frac1x++;
1285 x=(*buf1 / powers10[DIG_PER_DEC1 - frac1x]) ^ mask;
1286 switch (i)
1287 {
1288 case 1: mi_int1store(to, x); break;
1289 case 2: mi_int2store(to, x); break;
1290 case 3: mi_int3store(to, x); break;
1291 case 4: mi_int4store(to, x); break;
1292 default: DBUG_ASSERT(0);
1293 }
1294 to+=i;
1295 }
1296 if (fsize0 > fsize1)
1297 {
1298 uchar *to_end= orig_to + orig_fsize0 + orig_isize0;
1299
1300 while (fsize0-- > fsize1 && to < to_end)
1301 *to++= (uchar)mask;
1302 }
1303 orig_to[0]^= 0x80;
1304
1305 /* Check that we have written the whole decimal and nothing more */
1306 DBUG_ASSERT(to == orig_to + orig_fsize0 + orig_isize0);
1307 return error;
1308}
1309
1310/*
1311 Restores decimal from its binary fixed-length representation
1312
1313 SYNOPSIS
1314 bin2decimal()
1315 from - value to convert
1316 to - result
1317 precision/scale - see decimal_bin_size() below
1318
1319 NOTE
1320 see decimal2bin()
1321 the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1322
1323 RETURN VALUE
1324 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1325*/
1326
1327int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale)
1328{
1329 int error=E_DEC_OK, intg=precision-scale,
1330 intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1331 intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1,
1332 intg1=intg0+(intg0x>0), frac1=frac0+(frac0x>0);
1333 dec1 *buf=to->buf, mask=(*from & 0x80) ? 0 : -1;
1334 const uchar *stop;
1335 uchar *d_copy;
1336 int bin_size= decimal_bin_size(precision, scale);
1337
1338 sanity(to);
1339 d_copy= (uchar*) my_alloca(bin_size);
1340 memcpy(d_copy, from, bin_size);
1341 d_copy[0]^= 0x80;
1342 from= d_copy;
1343
1344 FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
1345 if (unlikely(error))
1346 {
1347 if (intg1 < intg0+(intg0x>0))
1348 {
1349 from+=dig2bytes[intg0x]+sizeof(dec1)*(intg0-intg1);
1350 frac0=frac0x=intg0x=0;
1351 intg0=intg1;
1352 }
1353 else
1354 {
1355 frac0x=0;
1356 frac0=frac1;
1357 }
1358 }
1359
1360 to->sign=(mask != 0);
1361 to->intg=intg0*DIG_PER_DEC1+intg0x;
1362 to->frac=frac0*DIG_PER_DEC1+frac0x;
1363
1364 if (intg0x)
1365 {
1366 int i=dig2bytes[intg0x];
1367 dec1 UNINIT_VAR(x);
1368 switch (i)
1369 {
1370 case 1: x=mi_sint1korr(from); break;
1371 case 2: x=mi_sint2korr(from); break;
1372 case 3: x=mi_sint3korr(from); break;
1373 case 4: x=mi_sint4korr(from); break;
1374 default: abort();
1375 }
1376 from+=i;
1377 *buf=x ^ mask;
1378 if (((ulonglong)*buf) >= (ulonglong) powers10[intg0x+1])
1379 goto err;
1380 if (buf > to->buf || *buf != 0)
1381 buf++;
1382 else
1383 to->intg-=intg0x;
1384 }
1385 for (stop=from+intg0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1386 {
1387 DBUG_ASSERT(sizeof(dec1) == 4);
1388 *buf=mi_sint4korr(from) ^ mask;
1389 if (((uint32)*buf) > DIG_MAX)
1390 goto err;
1391 if (buf > to->buf || *buf != 0)
1392 buf++;
1393 else
1394 to->intg-=DIG_PER_DEC1;
1395 }
1396 DBUG_ASSERT(to->intg >=0);
1397 for (stop=from+frac0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1398 {
1399 DBUG_ASSERT(sizeof(dec1) == 4);
1400 *buf=mi_sint4korr(from) ^ mask;
1401 if (((uint32)*buf) > DIG_MAX)
1402 goto err;
1403 buf++;
1404 }
1405 if (frac0x)
1406 {
1407 int i=dig2bytes[frac0x];
1408 dec1 UNINIT_VAR(x);
1409 switch (i)
1410 {
1411 case 1: x=mi_sint1korr(from); break;
1412 case 2: x=mi_sint2korr(from); break;
1413 case 3: x=mi_sint3korr(from); break;
1414 case 4: x=mi_sint4korr(from); break;
1415 default: abort();
1416 }
1417 *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
1418 if (((uint32)*buf) > DIG_MAX)
1419 goto err;
1420 buf++;
1421 }
1422 my_afree(d_copy);
1423
1424 /*
1425 No digits? We have read the number zero, of unspecified precision.
1426 Make it a proper zero, with non-zero precision.
1427 */
1428 if (to->intg == 0 && to->frac == 0)
1429 decimal_make_zero(to);
1430 return error;
1431
1432err:
1433 my_afree(d_copy);
1434 decimal_make_zero(to);
1435 return(E_DEC_BAD_NUM);
1436}
1437
1438/*
1439 Returns the size of array to hold a decimal with given precision and scale
1440
1441 RETURN VALUE
1442 size in dec1
1443 (multiply by sizeof(dec1) to get the size if bytes)
1444*/
1445
1446int decimal_size(int precision, int scale)
1447{
1448 DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
1449 return ROUND_UP(precision-scale)+ROUND_UP(scale);
1450}
1451
1452/*
1453 Returns the size of array to hold a binary representation of a decimal
1454
1455 RETURN VALUE
1456 size in bytes
1457*/
1458
1459int decimal_bin_size(int precision, int scale)
1460{
1461 int intg=precision-scale,
1462 intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1463 intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1;
1464
1465 DBUG_ASSERT(scale >= 0);
1466 DBUG_ASSERT(precision > 0);
1467 DBUG_ASSERT(scale <= precision);
1468 return intg0*sizeof(dec1)+dig2bytes[intg0x]+
1469 frac0*sizeof(dec1)+dig2bytes[frac0x];
1470}
1471
1472/*
1473 Rounds the decimal to "scale" digits
1474
1475 SYNOPSIS
1476 decimal_round()
1477 from - decimal to round,
1478 to - result buffer. from==to is allowed
1479 scale - to what position to round. can be negative!
1480 mode - round to nearest even or truncate
1481
1482 NOTES
1483 scale can be negative !
1484 one TRUNCATED error (line XXX below) isn't treated very logical :(
1485
1486 RETURN VALUE
1487 E_DEC_OK/E_DEC_TRUNCATED
1488*/
1489
1490int
1491decimal_round(const decimal_t *from, decimal_t *to, int scale,
1492 decimal_round_mode mode)
1493{
1494 int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
1495 frac1=ROUND_UP(from->frac), UNINIT_VAR(round_digit),
1496 intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len;
1497
1498 dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
1499 int first_dig;
1500
1501 sanity(to);
1502
1503 switch (mode) {
1504 case HALF_UP:
1505 case HALF_EVEN: round_digit=5; break;
1506 case CEILING: round_digit= from->sign ? 10 : 0; break;
1507 case FLOOR: round_digit= from->sign ? 0 : 10; break;
1508 case TRUNCATE: round_digit=10; break;
1509 default: DBUG_ASSERT(0);
1510 }
1511
1512 /*
1513 For my_decimal we always use len == DECIMAL_BUFF_LENGTH == 9
1514 For internal testing here (ifdef MAIN) we always use len == 100/4
1515 */
1516 DBUG_ASSERT(from->len == to->len);
1517
1518 if (unlikely(frac0+intg0 > len))
1519 {
1520 frac0=len-intg0;
1521 scale=frac0*DIG_PER_DEC1;
1522 error=E_DEC_TRUNCATED;
1523 }
1524
1525 if (scale+from->intg < 0)
1526 {
1527 decimal_make_zero(to);
1528 return E_DEC_OK;
1529 }
1530
1531 if (to != from)
1532 {
1533 dec1 *p0= buf0+intg0+MY_MAX(frac1, frac0);
1534 dec1 *p1= buf1+intg0+MY_MAX(frac1, frac0);
1535
1536 DBUG_ASSERT(p0 - buf0 <= len);
1537 DBUG_ASSERT(p1 - buf1 <= len);
1538
1539 while (buf0 < p0)
1540 *(--p1) = *(--p0);
1541
1542 buf0=to->buf;
1543 buf1=to->buf;
1544 to->sign=from->sign;
1545 to->intg=MY_MIN(intg0, len)*DIG_PER_DEC1;
1546 }
1547
1548 if (frac0 > frac1)
1549 {
1550 buf1+=intg0+frac1;
1551 while (frac0-- > frac1)
1552 *buf1++=0;
1553 goto done;
1554 }
1555
1556 if (scale >= from->frac)
1557 goto done; /* nothing to do */
1558
1559 buf0+=intg0+frac0-1;
1560 buf1+=intg0+frac0-1;
1561 if (scale == frac0*DIG_PER_DEC1)
1562 {
1563 int do_inc= FALSE;
1564 DBUG_ASSERT(frac0+intg0 >= 0);
1565 switch (round_digit) {
1566 case 0:
1567 {
1568 dec1 *p0= buf0 + (frac1-frac0);
1569 for (; p0 > buf0; p0--)
1570 {
1571 if (*p0)
1572 {
1573 do_inc= TRUE;
1574 break;
1575 }
1576 }
1577 break;
1578 }
1579 case 5:
1580 {
1581 x= buf0[1]/DIG_MASK;
1582 do_inc= (x>5) || ((x == 5) &&
1583 (mode == HALF_UP || (frac0+intg0 > 0 && *buf0 & 1)));
1584 break;
1585 }
1586 default:
1587 break;
1588 }
1589 if (do_inc)
1590 {
1591 if (frac0+intg0>0)
1592 (*buf1)++;
1593 else
1594 *(++buf1)=DIG_BASE;
1595 }
1596 else if (frac0+intg0==0)
1597 {
1598 decimal_make_zero(to);
1599 return E_DEC_OK;
1600 }
1601 }
1602 else
1603 {
1604 /* TODO - fix this code as it won't work for CEILING mode */
1605 int pos=frac0*DIG_PER_DEC1-scale-1;
1606 DBUG_ASSERT(frac0+intg0 > 0);
1607 x=*buf1 / powers10[pos];
1608 y=x % 10;
1609 if (y > round_digit ||
1610 (round_digit == 5 && y == 5 && (mode == HALF_UP || (x/10) & 1)))
1611 x+=10;
1612 *buf1=powers10[pos]*(x-y);
1613 }
1614 if (*buf1 >= DIG_BASE)
1615 {
1616 carry=1;
1617 *buf1-=DIG_BASE;
1618 while (carry && --buf1 >= to->buf)
1619 ADD(*buf1, *buf1, 0, carry);
1620 if (unlikely(carry))
1621 {
1622 /* shifting the number to create space for new digit */
1623 if (frac0+intg0 >= len)
1624 {
1625 frac0--;
1626 scale=frac0*DIG_PER_DEC1;
1627 error=E_DEC_TRUNCATED; /* XXX */
1628 }
1629 for (buf1=to->buf+intg0+MY_MAX(frac0,0); buf1 > to->buf; buf1--)
1630 {
1631 buf1[0]=buf1[-1];
1632 }
1633 *buf1=1;
1634 to->intg++;
1635 intg0++;
1636 }
1637 }
1638 else
1639 {
1640 for (;;)
1641 {
1642 if (likely(*buf1))
1643 break;
1644 if (buf1-- == to->buf)
1645 {
1646 /* making 'zero' with the proper scale */
1647 dec1 *p0= to->buf + frac0 + 1;
1648 to->intg=1;
1649 to->frac= MY_MAX(scale, 0);
1650 to->sign= 0;
1651 for (buf1= to->buf; buf1<p0; buf1++)
1652 *buf1= 0;
1653 return E_DEC_OK;
1654 }
1655 }
1656 }
1657 /*
1658 In case we're rounding e.g. 1.5e9 to 2.0e9, the decimal_digit_t's inside
1659 the buffer are as follows.
1660
1661 Before <1, 5e8>
1662 After <2, 5e8>
1663
1664 Hence we need to set the 2nd field to 0.
1665 The same holds if we round 1.5e-9 to 2e-9.
1666 */
1667 if (frac0 < frac1)
1668 {
1669 dec1 *buf= to->buf + ((scale == 0 && intg0 == 0) ? 1 : intg0 + frac0);
1670 dec1 *end= to->buf + len;
1671
1672 while (buf < end)
1673 *buf++=0;
1674 }
1675
1676 /* Here we check 999.9 -> 1000 case when we need to increase intg */
1677 first_dig= to->intg % DIG_PER_DEC1;
1678 if (first_dig && (*buf1 >= powers10[first_dig]))
1679 to->intg++;
1680
1681 if (scale<0)
1682 scale=0;
1683
1684done:
1685 to->frac=scale;
1686 return error;
1687}
1688
1689/*
1690 Returns the size of the result of the operation
1691
1692 SYNOPSIS
1693 decimal_result_size()
1694 from1 - operand of the unary operation or first operand of the
1695 binary operation
1696 from2 - second operand of the binary operation
1697 op - operation. one char '+', '-', '*', '/' are allowed
1698 others may be added later
1699 param - extra param to the operation. unused for '+', '-', '*'
1700 scale increment for '/'
1701
1702 NOTE
1703 returned valued may be larger than the actual buffer required
1704 in the operation, as decimal_result_size, by design, operates on
1705 precision/scale values only and not on the actual decimal number
1706
1707 RETURN VALUE
1708 size of to->buf array in dec1 elements. to get size in bytes
1709 multiply by sizeof(dec1)
1710*/
1711
1712int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, int param)
1713{
1714 switch (op) {
1715 case '-':
1716 return ROUND_UP(MY_MAX(from1->intg, from2->intg)) +
1717 ROUND_UP(MY_MAX(from1->frac, from2->frac));
1718 case '+':
1719 return ROUND_UP(MY_MAX(from1->intg, from2->intg)+1) +
1720 ROUND_UP(MY_MAX(from1->frac, from2->frac));
1721 case '*':
1722 return ROUND_UP(from1->intg+from2->intg)+
1723 ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
1724 case '/':
1725 return ROUND_UP(from1->intg+from2->intg+1+from1->frac+from2->frac+param);
1726 default: DBUG_ASSERT(0);
1727 }
1728 return -1; /* shut up the warning */
1729}
1730
1731static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1732{
1733 int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1734 frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1735 frac0=MY_MAX(frac1, frac2), intg0=MY_MAX(intg1, intg2), error;
1736 dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
1737
1738 sanity(to);
1739
1740 /* is there a need for extra word because of carry ? */
1741 x=intg1 > intg2 ? from1->buf[0] :
1742 intg2 > intg1 ? from2->buf[0] :
1743 from1->buf[0] + from2->buf[0] ;
1744 if (unlikely(x > DIG_MAX-1)) /* yes, there is */
1745 {
1746 intg0++;
1747 to->buf[0]=0; /* safety */
1748 }
1749
1750 FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
1751 if (unlikely(error == E_DEC_OVERFLOW))
1752 {
1753 max_decimal(to->len * DIG_PER_DEC1, 0, to);
1754 return error;
1755 }
1756
1757 buf0=to->buf+intg0+frac0;
1758
1759 to->sign=from1->sign;
1760 to->frac=MY_MAX(from1->frac, from2->frac);
1761 to->intg=intg0*DIG_PER_DEC1;
1762 if (unlikely(error))
1763 {
1764 set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
1765 set_if_smaller(frac1, frac0);
1766 set_if_smaller(frac2, frac0);
1767 set_if_smaller(intg1, intg0);
1768 set_if_smaller(intg2, intg0);
1769 }
1770
1771 /* part 1 - MY_MAX(frac) ... min (frac) */
1772 if (frac1 > frac2)
1773 {
1774 buf1=from1->buf+intg1+frac1;
1775 stop=from1->buf+intg1+frac2;
1776 buf2=from2->buf+intg2+frac2;
1777 stop2=from1->buf+(intg1 > intg2 ? intg1-intg2 : 0);
1778 }
1779 else
1780 {
1781 buf1=from2->buf+intg2+frac2;
1782 stop=from2->buf+intg2+frac1;
1783 buf2=from1->buf+intg1+frac1;
1784 stop2=from2->buf+(intg2 > intg1 ? intg2-intg1 : 0);
1785 }
1786 while (buf1 > stop)
1787 *--buf0=*--buf1;
1788
1789 /* part 2 - MY_MIN(frac) ... MY_MIN(intg) */
1790 carry=0;
1791 while (buf1 > stop2)
1792 {
1793 ADD(*--buf0, *--buf1, *--buf2, carry);
1794 }
1795
1796 /* part 3 - MY_MIN(intg) ... MY_MAX(intg) */
1797 buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
1798 ((stop=from2->buf)+intg2-intg1) ;
1799 while (buf1 > stop)
1800 {
1801 ADD(*--buf0, *--buf1, 0, carry);
1802 }
1803
1804 if (unlikely(carry))
1805 *--buf0=1;
1806 DBUG_ASSERT(buf0 == to->buf || buf0 == to->buf+1);
1807
1808 return error;
1809}
1810
1811/* to=from1-from2.
1812 if to==0, return -1/0/+1 - the result of the comparison */
1813static int do_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1814{
1815 int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1816 frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
1817 int frac0=MY_MAX(frac1, frac2), error;
1818 dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2;
1819 my_bool carry=0;
1820
1821 /* let carry:=1 if from2 > from1 */
1822 start1=buf1=from1->buf; stop1=buf1+intg1;
1823 start2=buf2=from2->buf; stop2=buf2+intg2;
1824 if (unlikely(*buf1 == 0))
1825 {
1826 while (buf1 < stop1 && *buf1 == 0)
1827 buf1++;
1828 start1=buf1;
1829 intg1= (int) (stop1-buf1);
1830 }
1831 if (unlikely(*buf2 == 0))
1832 {
1833 while (buf2 < stop2 && *buf2 == 0)
1834 buf2++;
1835 start2=buf2;
1836 intg2= (int) (stop2-buf2);
1837 }
1838 if (intg2 > intg1)
1839 carry=1;
1840 else if (intg2 == intg1)
1841 {
1842 dec1 *end1= stop1 + (frac1 - 1);
1843 dec1 *end2= stop2 + (frac2 - 1);
1844 while (unlikely((buf1 <= end1) && (*end1 == 0)))
1845 end1--;
1846 while (unlikely((buf2 <= end2) && (*end2 == 0)))
1847 end2--;
1848 frac1= (int) (end1 - stop1) + 1;
1849 frac2= (int) (end2 - stop2) + 1;
1850 while (buf1 <=end1 && buf2 <= end2 && *buf1 == *buf2)
1851 buf1++, buf2++;
1852 if (buf1 <= end1)
1853 {
1854 if (buf2 <= end2)
1855 carry= *buf2 > *buf1;
1856 else
1857 carry= 0;
1858 }
1859 else
1860 {
1861 if (buf2 <= end2)
1862 carry=1;
1863 else /* short-circuit everything: from1 == from2 */
1864 {
1865 if (to == 0) /* decimal_cmp() */
1866 return 0;
1867 decimal_make_zero(to);
1868 return E_DEC_OK;
1869 }
1870 }
1871 }
1872
1873 if (to == 0) /* decimal_cmp() */
1874 return carry == from1->sign ? 1 : -1;
1875
1876 sanity(to);
1877
1878 to->sign=from1->sign;
1879
1880 /* ensure that always from1 > from2 (and intg1 >= intg2) */
1881 if (carry)
1882 {
1883 swap_variables(const decimal_t *, from1, from2);
1884 swap_variables(dec1 *,start1, start2);
1885 swap_variables(int,intg1,intg2);
1886 swap_variables(int,frac1,frac2);
1887 to->sign= !to->sign;
1888 }
1889
1890 FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
1891 buf0=to->buf+intg1+frac0;
1892
1893 to->frac=MY_MAX(from1->frac, from2->frac);
1894 to->intg=intg1*DIG_PER_DEC1;
1895 if (unlikely(error))
1896 {
1897 set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
1898 set_if_smaller(frac1, frac0);
1899 set_if_smaller(frac2, frac0);
1900 set_if_smaller(intg2, intg1);
1901 }
1902 carry=0;
1903
1904 /* part 1 - MY_MAX(frac) ... min (frac) */
1905 if (frac1 > frac2)
1906 {
1907 buf1=start1+intg1+frac1;
1908 stop1=start1+intg1+frac2;
1909 buf2=start2+intg2+frac2;
1910 while (frac0-- > frac1)
1911 *--buf0=0;
1912 while (buf1 > stop1)
1913 *--buf0=*--buf1;
1914 }
1915 else
1916 {
1917 buf1=start1+intg1+frac1;
1918 buf2=start2+intg2+frac2;
1919 stop2=start2+intg2+frac1;
1920 while (frac0-- > frac2)
1921 *--buf0=0;
1922 while (buf2 > stop2)
1923 {
1924 SUB(*--buf0, 0, *--buf2, carry);
1925 }
1926 }
1927
1928 /* part 2 - MY_MIN(frac) ... intg2 */
1929 while (buf2 > start2)
1930 {
1931 SUB(*--buf0, *--buf1, *--buf2, carry);
1932 }
1933
1934 /* part 3 - intg2 ... intg1 */
1935 while (carry && buf1 > start1)
1936 {
1937 SUB(*--buf0, *--buf1, 0, carry);
1938 }
1939
1940 while (buf1 > start1)
1941 *--buf0=*--buf1;
1942
1943 while (buf0 > to->buf)
1944 *--buf0=0;
1945
1946 return error;
1947}
1948
1949int decimal_intg(const decimal_t *from)
1950{
1951 int res;
1952 remove_leading_zeroes(from, &res);
1953 return res;
1954}
1955
1956int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1957{
1958 if (likely(from1->sign == from2->sign))
1959 return do_add(from1, from2, to);
1960 return do_sub(from1, from2, to);
1961}
1962
1963int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1964{
1965 if (likely(from1->sign == from2->sign))
1966 return do_sub(from1, from2, to);
1967 return do_add(from1, from2, to);
1968}
1969
1970int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
1971{
1972 if (likely(from1->sign == from2->sign))
1973 return do_sub(from1, from2, 0);
1974 return from1->sign > from2->sign ? -1 : 1;
1975}
1976
1977int decimal_is_zero(const decimal_t *from)
1978{
1979 dec1 *buf1=from->buf,
1980 *end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
1981 while (buf1 < end)
1982 if (*buf1++)
1983 return 0;
1984 return 1;
1985}
1986
1987/*
1988 multiply two decimals
1989
1990 SYNOPSIS
1991 decimal_mul()
1992 from1, from2 - factors
1993 to - product
1994
1995 RETURN VALUE
1996 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW;
1997
1998 NOTES
1999 in this implementation, with sizeof(dec1)=4 we have DIG_PER_DEC1=9,
2000 and 63-digit number will take only 7 dec1 words (basically a 7-digit
2001 "base 999999999" number). Thus there's no need in fast multiplication
2002 algorithms, 7-digit numbers can be multiplied with a naive O(n*n)
2003 method.
2004
2005 XXX if this library is to be used with huge numbers of thousands of
2006 digits, fast multiplication must be implemented.
2007*/
2008int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2009{
2010 int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
2011 frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
2012 intg0=ROUND_UP(from1->intg+from2->intg),
2013 frac0=frac1+frac2, error, i, j, d_to_move;
2014 dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
2015 *start2, *stop2, *stop1, *start0, carry;
2016
2017 sanity(to);
2018
2019 i=intg0; /* save 'ideal' values */
2020 j=frac0;
2021 FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error); /* bound size */
2022 to->sign=from1->sign != from2->sign;
2023 to->frac=from1->frac+from2->frac; /* store size in digits */
2024 to->intg=intg0*DIG_PER_DEC1;
2025
2026 if (unlikely(error))
2027 {
2028 set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
2029 set_if_smaller(to->intg, intg0*DIG_PER_DEC1);
2030 if (unlikely(i > intg0)) /* bounded integer-part */
2031 {
2032 i-=intg0;
2033 j=i >> 1;
2034 intg1-= j;
2035 intg2-=i-j;
2036 frac1=frac2=0; /* frac0 is already 0 here */
2037 }
2038 else /* bounded fract part */
2039 {
2040 j-=frac0;
2041 i=j >> 1;
2042 if (frac1 <= frac2)
2043 {
2044 frac1-= i;
2045 frac2-=j-i;
2046 }
2047 else
2048 {
2049 frac2-= i;
2050 frac1-=j-i;
2051 }
2052 }
2053 }
2054 start0=to->buf+intg0+frac0-1;
2055 start2=buf2+frac2-1;
2056 stop1=buf1-intg1;
2057 stop2=buf2-intg2;
2058
2059 bzero(to->buf, (intg0+frac0)*sizeof(dec1));
2060
2061 for (buf1+=frac1-1; buf1 >= stop1; buf1--, start0--)
2062 {
2063 carry=0;
2064 for (buf0=start0, buf2=start2; buf2 >= stop2; buf2--, buf0--)
2065 {
2066 dec1 hi, lo;
2067 dec2 p= ((dec2)*buf1) * ((dec2)*buf2);
2068 hi=(dec1)(p/DIG_BASE);
2069 lo=(dec1)(p-((dec2)hi)*DIG_BASE);
2070 ADD2(*buf0, *buf0, lo, carry);
2071 carry+=hi;
2072 }
2073 if (carry)
2074 {
2075 if (buf0 < to->buf)
2076 return E_DEC_OVERFLOW;
2077 ADD2(*buf0, *buf0, 0, carry);
2078 }
2079 for (buf0--; carry; buf0--)
2080 {
2081 if (buf0 < to->buf)
2082 return E_DEC_OVERFLOW;
2083 ADD(*buf0, *buf0, 0, carry);
2084 }
2085 }
2086
2087 /* Now we have to check for -0.000 case */
2088 if (to->sign)
2089 {
2090 dec1 *buf= to->buf;
2091 dec1 *end= to->buf + intg0 + frac0;
2092 DBUG_ASSERT(buf != end);
2093 for (;;)
2094 {
2095 if (*buf)
2096 break;
2097 if (++buf == end)
2098 {
2099 /* We got decimal zero */
2100 decimal_make_zero(to);
2101 break;
2102 }
2103 }
2104 }
2105 buf1= to->buf;
2106 d_to_move= intg0 + ROUND_UP(to->frac);
2107 while (!*buf1 && (to->intg > DIG_PER_DEC1))
2108 {
2109 buf1++;
2110 to->intg-= DIG_PER_DEC1;
2111 d_to_move--;
2112 }
2113 if (to->buf < buf1)
2114 {
2115 dec1 *cur_d= to->buf;
2116 for (; d_to_move--; cur_d++, buf1++)
2117 *cur_d= *buf1;
2118 }
2119 return error;
2120}
2121
2122/*
2123 naive division algorithm (Knuth's Algorithm D in 4.3.1) -
2124 it's ok for short numbers
2125 also we're using alloca() to allocate a temporary buffer
2126
2127 XXX if this library is to be used with huge numbers of thousands of
2128 digits, fast division must be implemented and alloca should be
2129 changed to malloc (or at least fallback to malloc if alloca() fails)
2130 but then, decimal_mul() should be rewritten too :(
2131*/
2132static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
2133 decimal_t *to, decimal_t *mod, int scale_incr)
2134{
2135 int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2136 frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2137 UNINIT_VAR(error), i, intg0, frac0, len1, len2, dintg, div_mod=(!mod);
2138 dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1,
2139 *start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry;
2140 dec2 norm_factor, x, guess, y;
2141
2142 if (mod)
2143 to=mod;
2144
2145 sanity(to);
2146
2147 /* removing all the leading zeroes */
2148 i= ((prec2 - 1) % DIG_PER_DEC1) + 1;
2149 while (prec2 > 0 && *buf2 == 0)
2150 {
2151 prec2-= i;
2152 i= DIG_PER_DEC1;
2153 buf2++;
2154 }
2155 if (prec2 <= 0) /* short-circuit everything: from2 == 0 */
2156 return E_DEC_DIV_ZERO;
2157 for (i= (prec2 - 1) % DIG_PER_DEC1; *buf2 < powers10[i--]; prec2--) ;
2158 DBUG_ASSERT(prec2 > 0);
2159
2160 i=((prec1-1) % DIG_PER_DEC1)+1;
2161 while (prec1 > 0 && *buf1 == 0)
2162 {
2163 prec1-=i;
2164 i=DIG_PER_DEC1;
2165 buf1++;
2166 }
2167 if (prec1 <= 0)
2168 { /* short-circuit everything: from1 == 0 */
2169 decimal_make_zero(to);
2170 return E_DEC_OK;
2171 }
2172 for (i=(prec1-1) % DIG_PER_DEC1; *buf1 < powers10[i--]; prec1--) ;
2173 DBUG_ASSERT(prec1 > 0);
2174
2175 /* let's fix scale_incr, taking into account frac1,frac2 increase */
2176 if ((scale_incr-= frac1 - from1->frac + frac2 - from2->frac) < 0)
2177 scale_incr=0;
2178
2179 dintg=(prec1-frac1)-(prec2-frac2)+(*buf1 >= *buf2);
2180 if (dintg < 0)
2181 {
2182 dintg/=DIG_PER_DEC1;
2183 intg0=0;
2184 }
2185 else
2186 intg0=ROUND_UP(dintg);
2187 if (mod)
2188 {
2189 /* we're calculating N1 % N2.
2190 The result will have
2191 frac=MY_MAX(frac1, frac2), as for subtraction
2192 intg=intg2
2193 */
2194 to->sign=from1->sign;
2195 to->frac=MY_MAX(from1->frac, from2->frac);
2196 frac0=0;
2197 }
2198 else
2199 {
2200 /*
2201 we're calculating N1/N2. N1 is in the buf1, has prec1 digits
2202 N2 is in the buf2, has prec2 digits. Scales are frac1 and
2203 frac2 accordingly.
2204 Thus, the result will have
2205 frac = ROUND_UP(frac1+frac2+scale_incr)
2206 and
2207 intg = (prec1-frac1) - (prec2-frac2) + 1
2208 prec = intg+frac
2209 */
2210 frac0=ROUND_UP(frac1+frac2+scale_incr);
2211 FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
2212 to->sign=from1->sign != from2->sign;
2213 to->intg=intg0*DIG_PER_DEC1;
2214 to->frac=frac0*DIG_PER_DEC1;
2215 }
2216 buf0=to->buf;
2217 stop0=buf0+intg0+frac0;
2218 if (likely(div_mod))
2219 while (dintg++ < 0 && buf0 < &to->buf[to->len])
2220 {
2221 *buf0++=0;
2222 }
2223
2224 len1=(i=ROUND_UP(prec1))+ROUND_UP(2*frac2+scale_incr+1) + 1;
2225 set_if_bigger(len1, 3);
2226 if (!(tmp1=(dec1 *)my_alloca(len1*sizeof(dec1))))
2227 return E_DEC_OOM;
2228 memcpy(tmp1, buf1, i*sizeof(dec1));
2229 bzero(tmp1+i, (len1-i)*sizeof(dec1));
2230
2231 start1=tmp1;
2232 stop1=start1+len1;
2233 start2=buf2;
2234 stop2=buf2+ROUND_UP(prec2)-1;
2235
2236 /* removing end zeroes */
2237 while (*stop2 == 0 && stop2 >= start2)
2238 stop2--;
2239 len2= (int) (stop2++ - start2);
2240
2241 /*
2242 calculating norm2 (normalized *start2) - we need *start2 to be large
2243 (at least > DIG_BASE/2), but unlike Knuth's Alg. D we don't want to
2244 normalize input numbers (as we don't make a copy of the divisor).
2245 Thus we normalize first dec1 of buf2 only, and we'll normalize *start1
2246 on the fly for the purpose of guesstimation only.
2247 It's also faster, as we're saving on normalization of buf2
2248 */
2249 norm_factor=DIG_BASE/(*start2+1);
2250 norm2=(dec1)(norm_factor*start2[0]);
2251 if (unlikely(len2>0))
2252 norm2+=(dec1)(norm_factor*start2[1]/DIG_BASE);
2253
2254 if (*start1 < *start2)
2255 dcarry=*start1++;
2256 else
2257 dcarry=0;
2258
2259 /* main loop */
2260 for (; buf0 < stop0; buf0++)
2261 {
2262 /* short-circuit, if possible */
2263 if (unlikely(dcarry == 0 && *start1 < *start2))
2264 guess=0;
2265 else
2266 {
2267 /* D3: make a guess */
2268 x=start1[0]+((dec2)dcarry)*DIG_BASE;
2269 y=start1[1];
2270 guess=(norm_factor*x+norm_factor*y/DIG_BASE)/norm2;
2271 if (unlikely(guess >= DIG_BASE))
2272 guess=DIG_BASE-1;
2273 if (unlikely(len2>0))
2274 {
2275 /* hmm, this is a suspicious trick - I removed normalization here */
2276 if (start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y)
2277 guess--;
2278 if (unlikely(start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y))
2279 guess--;
2280 DBUG_ASSERT(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y);
2281 }
2282
2283 /* D4: multiply and subtract */
2284 buf2=stop2;
2285 buf1=start1+len2;
2286 DBUG_ASSERT(buf1 < stop1);
2287 for (carry=0; buf2 > start2; buf1--)
2288 {
2289 dec1 hi, lo;
2290 x=guess * (*--buf2);
2291 hi=(dec1)(x/DIG_BASE);
2292 lo=(dec1)(x-((dec2)hi)*DIG_BASE);
2293 SUB2(*buf1, *buf1, lo, carry);
2294 carry+=hi;
2295 }
2296 carry= dcarry < carry;
2297
2298 /* D5: check the remainder */
2299 if (unlikely(carry))
2300 {
2301 /* D6: correct the guess */
2302 guess--;
2303 buf2=stop2;
2304 buf1=start1+len2;
2305 for (carry=0; buf2 > start2; buf1--)
2306 {
2307 ADD(*buf1, *buf1, *--buf2, carry);
2308 }
2309 }
2310 }
2311 if (likely(div_mod))
2312 {
2313 DBUG_ASSERT(buf0 < to->buf + to->len);
2314 *buf0=(dec1)guess;
2315 }
2316#ifdef WORKAROUND_GCC_4_3_2_BUG
2317 dcarry= *(volatile dec1 *)start1;
2318#else
2319 dcarry= *start1;
2320#endif
2321 start1++;
2322 }
2323 if (mod)
2324 {
2325 /*
2326 now the result is in tmp1, it has
2327 intg=prec1-frac1
2328 frac=MY_MAX(frac1, frac2)=to->frac
2329 */
2330 if (dcarry)
2331 *--start1=dcarry;
2332 buf0=to->buf;
2333 intg0=(int) (ROUND_UP(prec1-frac1)-(start1-tmp1));
2334 frac0=ROUND_UP(to->frac);
2335 error=E_DEC_OK;
2336 if (unlikely(frac0==0 && intg0==0))
2337 {
2338 decimal_make_zero(to);
2339 goto done;
2340 }
2341 if (intg0<=0)
2342 {
2343 if (unlikely(-intg0 >= to->len))
2344 {
2345 decimal_make_zero(to);
2346 error=E_DEC_TRUNCATED;
2347 goto done;
2348 }
2349 stop1= start1 + frac0 + intg0;
2350 frac0+=intg0;
2351 to->intg=0;
2352 while (intg0++ < 0)
2353 *buf0++=0;
2354 }
2355 else
2356 {
2357 if (unlikely(intg0 > to->len))
2358 {
2359 frac0=0;
2360 intg0=to->len;
2361 error=E_DEC_OVERFLOW;
2362 goto done;
2363 }
2364 DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
2365 stop1=start1+frac0+intg0;
2366 to->intg=MY_MIN(intg0*DIG_PER_DEC1, from2->intg);
2367 }
2368 if (unlikely(intg0+frac0 > to->len))
2369 {
2370 stop1-=frac0+intg0-to->len;
2371 frac0=to->len-intg0;
2372 to->frac=frac0*DIG_PER_DEC1;
2373 error=E_DEC_TRUNCATED;
2374 }
2375 DBUG_ASSERT(buf0 + (stop1 - start1) <= to->buf + to->len);
2376 while (start1 < stop1)
2377 *buf0++=*start1++;
2378 }
2379done:
2380 my_afree(tmp1);
2381 return error;
2382}
2383
2384/*
2385 division of two decimals
2386
2387 SYNOPSIS
2388 decimal_div()
2389 from1 - dividend
2390 from2 - divisor
2391 to - quotient
2392
2393 RETURN VALUE
2394 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2395
2396 NOTES
2397 see do_div_mod()
2398*/
2399
2400int
2401decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to,
2402 int scale_incr)
2403{
2404 return do_div_mod(from1, from2, to, 0, scale_incr);
2405}
2406
2407/*
2408 modulus
2409
2410 SYNOPSIS
2411 decimal_mod()
2412 from1 - dividend
2413 from2 - divisor
2414 to - modulus
2415
2416 RETURN VALUE
2417 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2418
2419 NOTES
2420 see do_div_mod()
2421
2422 DESCRIPTION
2423 the modulus R in R = M mod N
2424
2425 is defined as
2426
2427 0 <= |R| < |M|
2428 sign R == sign M
2429 R = M - k*N, where k is integer
2430
2431 thus, there's no requirement for M or N to be integers
2432*/
2433
2434int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2435{
2436 return do_div_mod(from1, from2, 0, to, 0);
2437}
2438
2439#ifdef MAIN
2440
2441int full= 0;
2442decimal_t a, b, c;
2443char buf1[100], buf2[100], buf3[100];
2444
2445void dump_decimal(decimal_t *d)
2446{
2447 int i;
2448 printf("/* intg=%d, frac=%d, sign=%d, buf[]={", d->intg, d->frac, d->sign);
2449 for (i=0; i < ROUND_UP(d->frac)+ROUND_UP(d->intg)-1; i++)
2450 printf("%09d, ", d->buf[i]);
2451 printf("%09d} */ ", d->buf[i]);
2452}
2453
2454
2455void check_result_code(int actual, int want)
2456{
2457 if (actual != want)
2458 {
2459 printf("\n^^^^^^^^^^^^^ must return %d\n", want);
2460 exit(1);
2461 }
2462}
2463
2464
2465void print_decimal(decimal_t *d, const char *orig, int actual, int want)
2466{
2467 char s[100];
2468 int slen=sizeof(s);
2469
2470 if (full) dump_decimal(d);
2471 decimal2string(d, s, &slen, 0, 0, 0);
2472 printf("'%s'", s);
2473 check_result_code(actual, want);
2474 if (orig && strcmp(orig, s))
2475 {
2476 printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2477 exit(1);
2478 }
2479}
2480
2481void test_d2s()
2482{
2483 char s[100];
2484 int slen, res;
2485
2486 /***********************************/
2487 printf("==== decimal2string ====\n");
2488 a.buf[0]=12345; a.intg=5; a.frac=0; a.sign=0;
2489 slen=sizeof(s);
2490 res=decimal2string(&a, s, &slen, 0, 0, 0);
2491 dump_decimal(&a); printf(" --> res=%d str='%s' len=%d\n", res, s, slen);
2492
2493 a.buf[1]=987000000; a.frac=3;
2494 slen=sizeof(s);
2495 res=decimal2string(&a, s, &slen, 0, 0, 0);
2496 dump_decimal(&a); printf(" --> res=%d str='%s' len=%d\n", res, s, slen);
2497
2498 a.sign=1;
2499 slen=sizeof(s);
2500 res=decimal2string(&a, s, &slen, 0, 0, 0);
2501 dump_decimal(&a); printf(" --> res=%d str='%s' len=%d\n", res, s, slen);
2502
2503 slen=8;
2504 res=decimal2string(&a, s, &slen, 0, 0, 0);
2505 dump_decimal(&a); printf(" --> res=%d str='%s' len=%d\n", res, s, slen);
2506
2507 slen=5;
2508 res=decimal2string(&a, s, &slen, 0, 0, 0);
2509 dump_decimal(&a); printf(" --> res=%d str='%s' len=%d\n", res, s, slen);
2510
2511 a.buf[0]=987000000; a.frac=3; a.intg=0;
2512 slen=sizeof(s);
2513 res=decimal2string(&a, s, &slen, 0, 0, 0);
2514 dump_decimal(&a); printf(" --> res=%d str='%s' len=%d\n", res, s, slen);
2515}
2516
2517void test_s2d(const char *s, const char *orig, int ex)
2518{
2519 char s1[100], *end;
2520 int res;
2521 sprintf(s1, "'%s'", s);
2522 end= strend(s);
2523 printf("len=%2d %-30s => res=%d ", a.len, s1,
2524 (res= string2decimal(s, &a, &end)));
2525 print_decimal(&a, orig, res, ex);
2526 printf("\n");
2527}
2528
2529void test_d2f(const char *s, int ex)
2530{
2531 char s1[100], *end;
2532 double x;
2533 int res;
2534
2535 sprintf(s1, "'%s'", s);
2536 end= strend(s);
2537 string2decimal(s, &a, &end);
2538 res=decimal2double(&a, &x);
2539 if (full) dump_decimal(&a);
2540 printf("%-40s => res=%d %.*g\n", s1, res, a.intg+a.frac, x);
2541 check_result_code(res, ex);
2542}
2543
2544void test_d2b2d(const char *str, int p, int s, const char *orig, int ex)
2545{
2546 char s1[100], buf[100], *end;
2547 int res, i, size=decimal_bin_size(p, s);
2548
2549 sprintf(s1, "'%s'", str);
2550 end= strend(str);
2551 string2decimal(str, &a, &end);
2552 res=decimal2bin(&a, buf, p, s);
2553 printf("%-31s {%2d, %2d} => res=%d size=%-2d ", s1, p, s, res, size);
2554 if (full)
2555 {
2556 printf("0x");
2557 for (i=0; i < size; i++)
2558 printf("%02x", ((uchar *)buf)[i]);
2559 }
2560 res=bin2decimal(buf, &a, p, s);
2561 printf(" => res=%d ", res);
2562 print_decimal(&a, orig, res, ex);
2563 printf("\n");
2564}
2565
2566void test_f2d(double from, int ex)
2567{
2568 int res;
2569
2570 res=double2decimal(from, &a);
2571 printf("%-40.*f => res=%d ", DBL_DIG-2, from, res);
2572 print_decimal(&a, 0, res, ex);
2573 printf("\n");
2574}
2575
2576void test_ull2d(ulonglong from, const char *orig, int ex)
2577{
2578 char s[100];
2579 int res;
2580
2581 res=ulonglong2decimal(from, &a);
2582 longlong10_to_str(from,s,10);
2583 printf("%-40s => res=%d ", s, res);
2584 print_decimal(&a, orig, res, ex);
2585 printf("\n");
2586}
2587
2588void test_ll2d(longlong from, const char *orig, int ex)
2589{
2590 char s[100];
2591 int res;
2592
2593 res=longlong2decimal(from, &a);
2594 longlong10_to_str(from,s,-10);
2595 printf("%-40s => res=%d ", s, res);
2596 print_decimal(&a, orig, res, ex);
2597 printf("\n");
2598}
2599
2600void test_d2ull(const char *s, const char *orig, int ex)
2601{
2602 char s1[100], *end;
2603 ulonglong x;
2604 int res;
2605
2606 end= strend(s);
2607 string2decimal(s, &a, &end);
2608 res=decimal2ulonglong(&a, &x);
2609 if (full) dump_decimal(&a);
2610 longlong10_to_str(x,s1,10);
2611 printf("%-40s => res=%d %s\n", s, res, s1);
2612 check_result_code(res, ex);
2613 if (orig && strcmp(orig, s1))
2614 {
2615 printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2616 exit(1);
2617 }
2618}
2619
2620void test_d2ll(const char *s, const char *orig, int ex)
2621{
2622 char s1[100], *end;
2623 longlong x;
2624 int res;
2625
2626 end= strend(s);
2627 string2decimal(s, &a, &end);
2628 res=decimal2longlong(&a, &x);
2629 if (full) dump_decimal(&a);
2630 longlong10_to_str(x,s1,-10);
2631 printf("%-40s => res=%d %s\n", s, res, s1);
2632 check_result_code(res, ex);
2633 if (orig && strcmp(orig, s1))
2634 {
2635 printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2636 exit(1);
2637 }
2638}
2639
2640void test_da(const char *s1, const char *s2, const char *orig, int ex)
2641{
2642 char s[100], *end;
2643 int res;
2644 sprintf(s, "'%s' + '%s'", s1, s2);
2645 end= strend(s1);
2646 string2decimal(s1, &a, &end);
2647 end= strend(s2);
2648 string2decimal(s2, &b, &end);
2649 res=decimal_add(&a, &b, &c);
2650 printf("%-40s => res=%d ", s, res);
2651 print_decimal(&c, orig, res, ex);
2652 printf("\n");
2653}
2654
2655void test_ds(const char *s1, const char *s2, const char *orig, int ex)
2656{
2657 char s[100], *end;
2658 int res;
2659 sprintf(s, "'%s' - '%s'", s1, s2);
2660 end= strend(s1);
2661 string2decimal(s1, &a, &end);
2662 end= strend(s2);
2663 string2decimal(s2, &b, &end);
2664 res=decimal_sub(&a, &b, &c);
2665 printf("%-40s => res=%d ", s, res);
2666 print_decimal(&c, orig, res, ex);
2667 printf("\n");
2668}
2669
2670void test_dc(const char *s1, const char *s2, int orig)
2671{
2672 char s[100], *end;
2673 int res;
2674 sprintf(s, "'%s' <=> '%s'", s1, s2);
2675 end= strend(s1);
2676 string2decimal(s1, &a, &end);
2677 end= strend(s2);
2678 string2decimal(s2, &b, &end);
2679 res=decimal_cmp(&a, &b);
2680 printf("%-40s => res=%d\n", s, res);
2681 if (orig != res)
2682 {
2683 printf("\n^^^^^^^^^^^^^ must've been %d\n", orig);
2684 exit(1);
2685 }
2686}
2687
2688void test_dm(const char *s1, const char *s2, const char *orig, int ex)
2689{
2690 char s[100], *end;
2691 int res;
2692 sprintf(s, "'%s' * '%s'", s1, s2);
2693 end= strend(s1);
2694 string2decimal(s1, &a, &end);
2695 end= strend(s2);
2696 string2decimal(s2, &b, &end);
2697 res=decimal_mul(&a, &b, &c);
2698 printf("%-40s => res=%d ", s, res);
2699 print_decimal(&c, orig, res, ex);
2700 printf("\n");
2701}
2702
2703void test_dv(const char *s1, const char *s2, const char *orig, int ex)
2704{
2705 char s[100], *end;
2706 int res;
2707 sprintf(s, "'%s' / '%s'", s1, s2);
2708 end= strend(s1);
2709 string2decimal(s1, &a, &end);
2710 end= strend(s2);
2711 string2decimal(s2, &b, &end);
2712 res=decimal_div(&a, &b, &c, 5);
2713 printf("%-40s => res=%d ", s, res);
2714 check_result_code(res, ex);
2715 if (res == E_DEC_DIV_ZERO)
2716 printf("E_DEC_DIV_ZERO");
2717 else
2718 print_decimal(&c, orig, res, ex);
2719 printf("\n");
2720}
2721
2722void test_md(const char *s1, const char *s2, const char *orig, int ex)
2723{
2724 char s[100], *end;
2725 int res;
2726 sprintf(s, "'%s' %% '%s'", s1, s2);
2727 end= strend(s1);
2728 string2decimal(s1, &a, &end);
2729 end= strend(s2);
2730 string2decimal(s2, &b, &end);
2731 res=decimal_mod(&a, &b, &c);
2732 printf("%-40s => res=%d ", s, res);
2733 check_result_code(res, ex);
2734 if (res == E_DEC_DIV_ZERO)
2735 printf("E_DEC_DIV_ZERO");
2736 else
2737 print_decimal(&c, orig, res, ex);
2738 printf("\n");
2739}
2740
2741const char *round_mode[]=
2742{"TRUNCATE", "HALF_EVEN", "HALF_UP", "CEILING", "FLOOR"};
2743
2744void test_ro(const char *s1, int n, decimal_round_mode mode, const char *orig,
2745 int ex)
2746{
2747 char s[100], *end;
2748 int res;
2749 sprintf(s, "'%s', %d, %s", s1, n, round_mode[mode]);
2750 end= strend(s1);
2751 string2decimal(s1, &a, &end);
2752 res=decimal_round(&a, &b, n, mode);
2753 printf("%-40s => res=%d ", s, res);
2754 print_decimal(&b, orig, res, ex);
2755 printf("\n");
2756}
2757
2758
2759void test_mx(int precision, int frac, const char *orig)
2760{
2761 char s[100];
2762 sprintf(s, "%d, %d", precision, frac);
2763 max_decimal(precision, frac, &a);
2764 printf("%-40s => ", s);
2765 print_decimal(&a, orig, 0, 0);
2766 printf("\n");
2767}
2768
2769
2770void test_pr(const char *s1, int prec, int dec, char filler, const char *orig,
2771 int ex)
2772{
2773 char s[100], *end;
2774 char s2[100];
2775 int slen= sizeof(s2);
2776 int res;
2777
2778 sprintf(s, filler ? "'%s', %d, %d, '%c'" : "'%s', %d, %d, '\\0'",
2779 s1, prec, dec, filler);
2780 end= strend(s1);
2781 string2decimal(s1, &a, &end);
2782 res= decimal2string(&a, s2, &slen, prec, dec, filler);
2783 printf("%-40s => res=%d '%s'", s, res, s2);
2784 check_result_code(res, ex);
2785 if (orig && strcmp(orig, s2))
2786 {
2787 printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2788 exit(1);
2789 }
2790 printf("\n");
2791}
2792
2793
2794void test_sh(const char *s1, int shift, const char *orig, int ex)
2795{
2796 char s[100], *end;
2797 int res;
2798 sprintf(s, "'%s' %s %d", s1, ((shift < 0) ? ">>" : "<<"), abs(shift));
2799 end= strend(s1);
2800 string2decimal(s1, &a, &end);
2801 res= decimal_shift(&a, shift);
2802 printf("%-40s => res=%d ", s, res);
2803 print_decimal(&a, orig, res, ex);
2804 printf("\n");
2805}
2806
2807
2808void test_fr(const char *s1, const char *orig)
2809{
2810 char s[100], *end;
2811 sprintf(s, "'%s'", s1);
2812 printf("%-40s => ", s);
2813 end= strend(s1);
2814 string2decimal(s1, &a, &end);
2815 a.frac= decimal_actual_fraction(&a);
2816 print_decimal(&a, orig, 0, 0);
2817 printf("\n");
2818}
2819
2820
2821int main()
2822{
2823 a.buf=(void*)buf1;
2824 a.len=sizeof(buf1)/sizeof(dec1);
2825 b.buf=(void*)buf2;
2826 b.len=sizeof(buf2)/sizeof(dec1);
2827 c.buf=(void*)buf3;
2828 c.len=sizeof(buf3)/sizeof(dec1);
2829
2830 if (full)
2831 test_d2s();
2832
2833 printf("==== string2decimal ====\n");
2834 test_s2d("12345", "12345", 0);
2835 test_s2d("12345.", "12345", 0);
2836 test_s2d("123.45", "123.45", 0);
2837 test_s2d("-123.45", "-123.45", 0);
2838 test_s2d(".00012345000098765", "0.00012345000098765", 0);
2839 test_s2d(".12345000098765", "0.12345000098765", 0);
2840 test_s2d("-.000000012345000098765", "-0.000000012345000098765", 0);
2841 test_s2d("1234500009876.5", "1234500009876.5", 0);
2842 a.len=1;
2843 test_s2d("123450000098765", "98765", 2);
2844 test_s2d("123450.000098765", "123450", 1);
2845 a.len=sizeof(buf1)/sizeof(dec1);
2846 test_s2d("123E5", "12300000", 0);
2847 test_s2d("123E-2", "1.23", 0);
2848
2849 printf("==== decimal2double ====\n");
2850 test_d2f("12345", 0);
2851 test_d2f("123.45", 0);
2852 test_d2f("-123.45", 0);
2853 test_d2f("0.00012345000098765", 0);
2854 test_d2f("1234500009876.5", 0);
2855
2856 printf("==== double2decimal ====\n");
2857 test_f2d(12345, 0);
2858 test_f2d(1.0/3, 0);
2859 test_f2d(-123.45, 0);
2860 test_f2d(0.00012345000098765, 0);
2861 test_f2d(1234500009876.5, 0);
2862
2863 printf("==== ulonglong2decimal ====\n");
2864 test_ull2d(ULL(12345), "12345", 0);
2865 test_ull2d(ULL(0), "0", 0);
2866 test_ull2d(ULL(18446744073709551615), "18446744073709551615", 0);
2867
2868 printf("==== decimal2ulonglong ====\n");
2869 test_d2ull("12345", "12345", 0);
2870 test_d2ull("0", "0", 0);
2871 test_d2ull("18446744073709551615", "18446744073709551615", 0);
2872 test_d2ull("18446744073709551616", "18446744073", 2);
2873 test_d2ull("-1", "0", 2);
2874 test_d2ull("1.23", "1", 1);
2875 test_d2ull("9999999999999999999999999.000", "9999999999999999", 2);
2876
2877 printf("==== longlong2decimal ====\n");
2878 test_ll2d(LL(-12345), "-12345", 0);
2879 test_ll2d(LL(-1), "-1", 0);
2880 test_ll2d(LL(-9223372036854775807), "-9223372036854775807", 0);
2881 test_ll2d(ULL(9223372036854775808), "-9223372036854775808", 0);
2882
2883 printf("==== decimal2longlong ====\n");
2884 test_d2ll("18446744073709551615", "18446744073", 2);
2885 test_d2ll("-1", "-1", 0);
2886 test_d2ll("-1.23", "-1", 1);
2887 test_d2ll("-9223372036854775807", "-9223372036854775807", 0);
2888 test_d2ll("-9223372036854775808", "-9223372036854775808", 0);
2889 test_d2ll("9223372036854775808", "9223372036854775807", 2);
2890
2891 printf("==== do_add ====\n");
2892 test_da(".00012345000098765" ,"123.45", "123.45012345000098765", 0);
2893 test_da(".1" ,".45", "0.55", 0);
2894 test_da("1234500009876.5" ,".00012345000098765", "1234500009876.50012345000098765", 0);
2895 test_da("9999909999999.5" ,".555", "9999910000000.055", 0);
2896 test_da("99999999" ,"1", "100000000", 0);
2897 test_da("989999999" ,"1", "990000000", 0);
2898 test_da("999999999" ,"1", "1000000000", 0);
2899 test_da("12345" ,"123.45", "12468.45", 0);
2900 test_da("-12345" ,"-123.45", "-12468.45", 0);
2901 test_ds("-12345" ,"123.45", "-12468.45", 0);
2902 test_ds("12345" ,"-123.45", "12468.45", 0);
2903
2904 printf("==== do_sub ====\n");
2905 test_ds(".00012345000098765", "123.45","-123.44987654999901235", 0);
2906 test_ds("1234500009876.5", ".00012345000098765","1234500009876.49987654999901235", 0);
2907 test_ds("9999900000000.5", ".555","9999899999999.945", 0);
2908 test_ds("1111.5551", "1111.555","0.0001", 0);
2909 test_ds(".555", ".555","0", 0);
2910 test_ds("10000000", "1","9999999", 0);
2911 test_ds("1000001000", ".1","1000000999.9", 0);
2912 test_ds("1000000000", ".1","999999999.9", 0);
2913 test_ds("12345", "123.45","12221.55", 0);
2914 test_ds("-12345", "-123.45","-12221.55", 0);
2915 test_da("-12345", "123.45","-12221.55", 0);
2916 test_da("12345", "-123.45","12221.55", 0);
2917 test_ds("123.45", "12345","-12221.55", 0);
2918 test_ds("-123.45", "-12345","12221.55", 0);
2919 test_da("123.45", "-12345","-12221.55", 0);
2920 test_da("-123.45", "12345","12221.55", 0);
2921 test_da("5", "-6.0","-1.0", 0);
2922
2923 printf("==== decimal_mul ====\n");
2924 test_dm("12", "10","120", 0);
2925 test_dm("-123.456", "98765.4321","-12193185.1853376", 0);
2926 test_dm("-123456000000", "98765432100000","-12193185185337600000000000", 0);
2927 test_dm("123456", "987654321","121931851853376", 0);
2928 test_dm("123456", "9876543210","1219318518533760", 0);
2929 test_dm("123", "0.01","1.23", 0);
2930 test_dm("123", "0","0", 0);
2931
2932 printf("==== decimal_div ====\n");
2933 test_dv("120", "10","12.000000000", 0);
2934 test_dv("123", "0.01","12300.000000000", 0);
2935 test_dv("120", "100000000000.00000","0.000000001200000000", 0);
2936 test_dv("123", "0","", 4);
2937 test_dv("0", "0", "", 4);
2938 test_dv("-12193185.1853376", "98765.4321","-123.456000000000000000", 0);
2939 test_dv("121931851853376", "987654321","123456.000000000", 0);
2940 test_dv("0", "987","0", 0);
2941 test_dv("1", "3","0.333333333", 0);
2942 test_dv("1.000000000000", "3","0.333333333333333333", 0);
2943 test_dv("1", "1","1.000000000", 0);
2944 test_dv("0.0123456789012345678912345", "9999999999","0.000000000001234567890246913578148141", 0);
2945 test_dv("10.333000000", "12.34500","0.837019036046982584042122316", 0);
2946 test_dv("10.000000000060", "2","5.000000000030000000", 0);
2947
2948 printf("==== decimal_mod ====\n");
2949 test_md("234","10","4", 0);
2950 test_md("234.567","10.555","2.357", 0);
2951 test_md("-234.567","10.555","-2.357", 0);
2952 test_md("234.567","-10.555","2.357", 0);
2953 c.buf[1]=0x3ABECA;
2954 test_md("99999999999999999999999999999999999999","3","0", 0);
2955 if (c.buf[1] != 0x3ABECA)
2956 {
2957 printf("%X - overflow\n", c.buf[1]);
2958 exit(1);
2959 }
2960
2961 printf("==== decimal2bin/bin2decimal ====\n");
2962 test_d2b2d("-10.55", 4, 2,"-10.55", 0);
2963 test_d2b2d("0.0123456789012345678912345", 30, 25,"0.0123456789012345678912345", 0);
2964 test_d2b2d("12345", 5, 0,"12345", 0);
2965 test_d2b2d("12345", 10, 3,"12345.000", 0);
2966 test_d2b2d("123.45", 10, 3,"123.450", 0);
2967 test_d2b2d("-123.45", 20, 10,"-123.4500000000", 0);
2968 test_d2b2d(".00012345000098765", 15, 14,"0.00012345000098", 0);
2969 test_d2b2d(".00012345000098765", 22, 20,"0.00012345000098765000", 0);
2970 test_d2b2d(".12345000098765", 30, 20,"0.12345000098765000000", 0);
2971 test_d2b2d("-.000000012345000098765", 30, 20,"-0.00000001234500009876", 0);
2972 test_d2b2d("1234500009876.5", 30, 5,"1234500009876.50000", 0);
2973 test_d2b2d("111111111.11", 10, 2,"11111111.11", 0);
2974 test_d2b2d("000000000.01", 7, 3,"0.010", 0);
2975 test_d2b2d("123.4", 10, 2, "123.40", 0);
2976
2977
2978 printf("==== decimal_cmp ====\n");
2979 test_dc("12","13",-1);
2980 test_dc("13","12",1);
2981 test_dc("-10","10",-1);
2982 test_dc("10","-10",1);
2983 test_dc("-12","-13",1);
2984 test_dc("0","12",-1);
2985 test_dc("-10","0",-1);
2986 test_dc("4","4",0);
2987
2988 printf("==== decimal_round ====\n");
2989 test_ro("5678.123451",-4,TRUNCATE,"0", 0);
2990 test_ro("5678.123451",-3,TRUNCATE,"5000", 0);
2991 test_ro("5678.123451",-2,TRUNCATE,"5600", 0);
2992 test_ro("5678.123451",-1,TRUNCATE,"5670", 0);
2993 test_ro("5678.123451",0,TRUNCATE,"5678", 0);
2994 test_ro("5678.123451",1,TRUNCATE,"5678.1", 0);
2995 test_ro("5678.123451",2,TRUNCATE,"5678.12", 0);
2996 test_ro("5678.123451",3,TRUNCATE,"5678.123", 0);
2997 test_ro("5678.123451",4,TRUNCATE,"5678.1234", 0);
2998 test_ro("5678.123451",5,TRUNCATE,"5678.12345", 0);
2999 test_ro("5678.123451",6,TRUNCATE,"5678.123451", 0);
3000 test_ro("-5678.123451",-4,TRUNCATE,"0", 0);
3001 memset(buf2, 33, sizeof(buf2));
3002 test_ro("99999999999999999999999999999999999999",-31,TRUNCATE,"99999990000000000000000000000000000000", 0);
3003 test_ro("15.1",0,HALF_UP,"15", 0);
3004 test_ro("15.5",0,HALF_UP,"16", 0);
3005 test_ro("15.9",0,HALF_UP,"16", 0);
3006 test_ro("-15.1",0,HALF_UP,"-15", 0);
3007 test_ro("-15.5",0,HALF_UP,"-16", 0);
3008 test_ro("-15.9",0,HALF_UP,"-16", 0);
3009 test_ro("15.1",1,HALF_UP,"15.1", 0);
3010 test_ro("-15.1",1,HALF_UP,"-15.1", 0);
3011 test_ro("15.17",1,HALF_UP,"15.2", 0);
3012 test_ro("15.4",-1,HALF_UP,"20", 0);
3013 test_ro("-15.4",-1,HALF_UP,"-20", 0);
3014 test_ro("5.4",-1,HALF_UP,"10", 0);
3015 test_ro(".999", 0, HALF_UP, "1", 0);
3016 memset(buf2, 33, sizeof(buf2));
3017 test_ro("999999999", -9, HALF_UP, "1000000000", 0);
3018 test_ro("15.1",0,HALF_EVEN,"15", 0);
3019 test_ro("15.5",0,HALF_EVEN,"16", 0);
3020 test_ro("14.5",0,HALF_EVEN,"14", 0);
3021 test_ro("15.9",0,HALF_EVEN,"16", 0);
3022 test_ro("15.1",0,CEILING,"16", 0);
3023 test_ro("-15.1",0,CEILING,"-15", 0);
3024 test_ro("15.1",0,FLOOR,"15", 0);
3025 test_ro("-15.1",0,FLOOR,"-16", 0);
3026 test_ro("999999999999999999999.999", 0, CEILING,"1000000000000000000000", 0);
3027 test_ro("-999999999999999999999.999", 0, FLOOR,"-1000000000000000000000", 0);
3028
3029 b.buf[0]=DIG_BASE+1;
3030 b.buf++;
3031 test_ro(".3", 0, HALF_UP, "0", 0);
3032 b.buf--;
3033 if (b.buf[0] != DIG_BASE+1)
3034 {
3035 printf("%d - underflow\n", b.buf[0]);
3036 exit(1);
3037 }
3038
3039 printf("==== max_decimal ====\n");
3040 test_mx(1,1,"0.9");
3041 test_mx(1,0,"9");
3042 test_mx(2,1,"9.9");
3043 test_mx(4,2,"99.99");
3044 test_mx(6,3,"999.999");
3045 test_mx(8,4,"9999.9999");
3046 test_mx(10,5,"99999.99999");
3047 test_mx(12,6,"999999.999999");
3048 test_mx(14,7,"9999999.9999999");
3049 test_mx(16,8,"99999999.99999999");
3050 test_mx(18,9,"999999999.999999999");
3051 test_mx(20,10,"9999999999.9999999999");
3052 test_mx(20,20,"0.99999999999999999999");
3053 test_mx(20,0,"99999999999999999999");
3054 test_mx(40,20,"99999999999999999999.99999999999999999999");
3055
3056 printf("==== decimal2string ====\n");
3057 test_pr("123.123", 0, 0, 0, "123.123", 0);
3058 test_pr("123.123", 7, 3, '0', "123.123", 0);
3059 test_pr("123.123", 9, 3, '0', "00123.123", 0);
3060 test_pr("123.123", 9, 4, '0', "0123.1230", 0);
3061 test_pr("123.123", 9, 5, '0', "123.12300", 0);
3062 test_pr("123.123", 9, 2, '0', "000123.12", 1);
3063 test_pr("123.123", 9, 6, '0', "23.123000", 2);
3064
3065 printf("==== decimal_shift ====\n");
3066 test_sh("123.123", 1, "1231.23", 0);
3067 test_sh("123457189.123123456789000", 1, "1234571891.23123456789", 0);
3068 test_sh("123457189.123123456789000", 4, "1234571891231.23456789", 0);
3069 test_sh("123457189.123123456789000", 8, "12345718912312345.6789", 0);
3070 test_sh("123457189.123123456789000", 9, "123457189123123456.789", 0);
3071 test_sh("123457189.123123456789000", 10, "1234571891231234567.89", 0);
3072 test_sh("123457189.123123456789000", 17, "12345718912312345678900000", 0);
3073 test_sh("123457189.123123456789000", 18, "123457189123123456789000000", 0);
3074 test_sh("123457189.123123456789000", 19, "1234571891231234567890000000", 0);
3075 test_sh("123457189.123123456789000", 26, "12345718912312345678900000000000000", 0);
3076 test_sh("123457189.123123456789000", 27, "123457189123123456789000000000000000", 0);
3077 test_sh("123457189.123123456789000", 28, "1234571891231234567890000000000000000", 0);
3078 test_sh("000000000000000000000000123457189.123123456789000", 26, "12345718912312345678900000000000000", 0);
3079 test_sh("00000000123457189.123123456789000", 27, "123457189123123456789000000000000000", 0);
3080 test_sh("00000000000000000123457189.123123456789000", 28, "1234571891231234567890000000000000000", 0);
3081 test_sh("123", 1, "1230", 0);
3082 test_sh("123", 10, "1230000000000", 0);
3083 test_sh(".123", 1, "1.23", 0);
3084 test_sh(".123", 10, "1230000000", 0);
3085 test_sh(".123", 14, "12300000000000", 0);
3086 test_sh("000.000", 1000, "0", 0);
3087 test_sh("000.", 1000, "0", 0);
3088 test_sh(".000", 1000, "0", 0);
3089 test_sh("1", 1000, "1", 2);
3090 test_sh("123.123", -1, "12.3123", 0);
3091 test_sh("123987654321.123456789000", -1, "12398765432.1123456789", 0);
3092 test_sh("123987654321.123456789000", -2, "1239876543.21123456789", 0);
3093 test_sh("123987654321.123456789000", -3, "123987654.321123456789", 0);
3094 test_sh("123987654321.123456789000", -8, "1239.87654321123456789", 0);
3095 test_sh("123987654321.123456789000", -9, "123.987654321123456789", 0);
3096 test_sh("123987654321.123456789000", -10, "12.3987654321123456789", 0);
3097 test_sh("123987654321.123456789000", -11, "1.23987654321123456789", 0);
3098 test_sh("123987654321.123456789000", -12, "0.123987654321123456789", 0);
3099 test_sh("123987654321.123456789000", -13, "0.0123987654321123456789", 0);
3100 test_sh("123987654321.123456789000", -14, "0.00123987654321123456789", 0);
3101 test_sh("00000087654321.123456789000", -14, "0.00000087654321123456789", 0);
3102 a.len= 2;
3103 test_sh("123.123", -2, "1.23123", 0);
3104 test_sh("123.123", -3, "0.123123", 0);
3105 test_sh("123.123", -6, "0.000123123", 0);
3106 test_sh("123.123", -7, "0.0000123123", 0);
3107 test_sh("123.123", -15, "0.000000000000123123", 0);
3108 test_sh("123.123", -16, "0.000000000000012312", 1);
3109 test_sh("123.123", -17, "0.000000000000001231", 1);
3110 test_sh("123.123", -18, "0.000000000000000123", 1);
3111 test_sh("123.123", -19, "0.000000000000000012", 1);
3112 test_sh("123.123", -20, "0.000000000000000001", 1);
3113 test_sh("123.123", -21, "0", 1);
3114 test_sh(".000000000123", -1, "0.0000000000123", 0);
3115 test_sh(".000000000123", -6, "0.000000000000000123", 0);
3116 test_sh(".000000000123", -7, "0.000000000000000012", 1);
3117 test_sh(".000000000123", -8, "0.000000000000000001", 1);
3118 test_sh(".000000000123", -9, "0", 1);
3119 test_sh(".000000000123", 1, "0.00000000123", 0);
3120 test_sh(".000000000123", 8, "0.0123", 0);
3121 test_sh(".000000000123", 9, "0.123", 0);
3122 test_sh(".000000000123", 10, "1.23", 0);
3123 test_sh(".000000000123", 17, "12300000", 0);
3124 test_sh(".000000000123", 18, "123000000", 0);
3125 test_sh(".000000000123", 19, "1230000000", 0);
3126 test_sh(".000000000123", 20, "12300000000", 0);
3127 test_sh(".000000000123", 21, "123000000000", 0);
3128 test_sh(".000000000123", 22, "1230000000000", 0);
3129 test_sh(".000000000123", 23, "12300000000000", 0);
3130 test_sh(".000000000123", 24, "123000000000000", 0);
3131 test_sh(".000000000123", 25, "1230000000000000", 0);
3132 test_sh(".000000000123", 26, "12300000000000000", 0);
3133 test_sh(".000000000123", 27, "123000000000000000", 0);
3134 test_sh(".000000000123", 28, "0.000000000123", 2);
3135 test_sh("123456789.987654321", -1, "12345678.998765432", 1);
3136 test_sh("123456789.987654321", -2, "1234567.899876543", 1);
3137 test_sh("123456789.987654321", -8, "1.234567900", 1);
3138 test_sh("123456789.987654321", -9, "0.123456789987654321", 0);
3139 test_sh("123456789.987654321", -10, "0.012345678998765432", 1);
3140 test_sh("123456789.987654321", -17, "0.000000001234567900", 1);
3141 test_sh("123456789.987654321", -18, "0.000000000123456790", 1);
3142 test_sh("123456789.987654321", -19, "0.000000000012345679", 1);
3143 test_sh("123456789.987654321", -26, "0.000000000000000001", 1);
3144 test_sh("123456789.987654321", -27, "0", 1);
3145 test_sh("123456789.987654321", 1, "1234567900", 1);
3146 test_sh("123456789.987654321", 2, "12345678999", 1);
3147 test_sh("123456789.987654321", 4, "1234567899877", 1);
3148 test_sh("123456789.987654321", 8, "12345678998765432", 1);
3149 test_sh("123456789.987654321", 9, "123456789987654321", 0);
3150 test_sh("123456789.987654321", 10, "123456789.987654321", 2);
3151 test_sh("123456789.987654321", 0, "123456789.987654321", 0);
3152 a.len= sizeof(buf1)/sizeof(dec1);
3153
3154 printf("==== decimal_actual_fraction ====\n");
3155 test_fr("1.123456789000000000", "1.123456789");
3156 test_fr("1.12345678000000000", "1.12345678");
3157 test_fr("1.1234567000000000", "1.1234567");
3158 test_fr("1.123456000000000", "1.123456");
3159 test_fr("1.12345000000000", "1.12345");
3160 test_fr("1.1234000000000", "1.1234");
3161 test_fr("1.123000000000", "1.123");
3162 test_fr("1.12000000000", "1.12");
3163 test_fr("1.1000000000", "1.1");
3164 test_fr("1.000000000", "1");
3165 test_fr("1.0", "1");
3166 test_fr("10000000000000000000.0", "10000000000000000000");
3167
3168 return 0;
3169}
3170#endif
3171