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-1335  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 
26 4.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 
58 5.3 <literal>, page 143
59 
60   <exact numeric literal> ::=
61     <unsigned integer> [ <period> [ <unsigned integer> ] ]
62   | <period> <unsigned integer>
63 
64 6.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 
84 6.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 */
122 typedef decimal_digit_t dec1;
123 typedef 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)
130 static const dec1 powers10[DIG_PER_DEC1+1]={
131   1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
132 static const int dig2bytes[DIG_PER_DEC1+1]={0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
133 static const dec1 frac_max[DIG_PER_DEC1-1]={
134   900000000, 990000000, 999000000,
135   999900000, 999990000, 999999000,
136   999999900, 999999990 };
137 
ROUND_UP(int x)138 static 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 
max_decimal(int precision,int frac,decimal_t * to)228 void 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 
remove_leading_zeroes(const decimal_t * from,int * intg_result)255 static 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 
decimal_actual_fraction(const decimal_t * from)286 int 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 
decimal2string(const decimal_t * from,char * to,int * to_len,int fixed_precision,int fixed_decimals,char filler)333 int 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 
digits_bounds(decimal_t * from,int * start_result,int * end_result)453 static 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 
do_mini_left_shift(decimal_t * dec,int shift,int beg,int last)520 void 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 
do_mini_right_shift(decimal_t * dec,int shift,int beg,int last)550 void 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 
decimal_shift(decimal_t * dec,int shift)583 int 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 
792 int
internal_str2dec(const char * from,decimal_t * to,char ** end,my_bool fixed)793 internal_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   /*
816     If the integer part is long enough and it has multiple leading zeros,
817     let's trim them, so this expression can return 1 without overflowing:
818       CAST(CONCAT(REPEAT('0',90),'1') AS DECIMAL(10))
819   */
820   if (intg > DIG_PER_DEC1 && s1[0] == '0' && s1[1] == '0')
821   {
822     /*
823       Keep at least one digit, to avoid an empty string.
824       So we trim '0000' to '0' rather than to ''.
825       Otherwise the below code (converting digits to to->buf)
826       would fail on a fatal error.
827     */
828     const char *iend= s - 1;
829     for ( ; s1 < iend && *s1 == '0'; s1++)
830     { }
831     intg= (int) (s-s1);
832   }
833   if (s < end_of_string && *s=='.')
834   {
835     endp= s+1;
836     while (endp < end_of_string && my_isdigit(&my_charset_latin1, *endp))
837       endp++;
838     frac= (int) (endp - s - 1);
839   }
840   else
841   {
842     frac= 0;
843     endp= s;
844   }
845 
846   *end= (char*) endp;
847 
848   if (frac+intg == 0)
849     goto fatal_error;
850 
851   error= 0;
852   if (fixed)
853   {
854     if (frac > to->frac)
855     {
856       error=E_DEC_TRUNCATED;
857       frac=to->frac;
858     }
859     if (intg > to->intg)
860     {
861       error=E_DEC_OVERFLOW;
862       intg=to->intg;
863     }
864     intg1=ROUND_UP(intg);
865     frac1=ROUND_UP(frac);
866     if (intg1+frac1 > to->len)
867     {
868       error= E_DEC_OOM;
869       goto fatal_error;
870     }
871   }
872   else
873   {
874     intg1=ROUND_UP(intg);
875     frac1=ROUND_UP(frac);
876     FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
877     if (unlikely(error))
878     {
879       frac=frac1*DIG_PER_DEC1;
880       if (error == E_DEC_OVERFLOW)
881         intg=intg1*DIG_PER_DEC1;
882     }
883   }
884   /* Error is guaranteed to be set here */
885   to->intg=intg;
886   to->frac=frac;
887 
888   buf=to->buf+intg1;
889   s1=s;
890 
891   for (x=0, i=0; intg; intg--)
892   {
893     x+= (*--s - '0')*powers10[i];
894 
895     if (unlikely(++i == DIG_PER_DEC1))
896     {
897       *--buf=x;
898       x=0;
899       i=0;
900     }
901   }
902   if (i)
903     *--buf=x;
904 
905   buf=to->buf+intg1;
906   for (x=0, i=0; frac; frac--)
907   {
908     x= (*++s1 - '0') + x*10;
909 
910     if (unlikely(++i == DIG_PER_DEC1))
911     {
912       *buf++=x;
913       x=0;
914       i=0;
915     }
916   }
917   if (i)
918     *buf=x*powers10[DIG_PER_DEC1-i];
919 
920   /* Handle exponent */
921   if (endp+1 < end_of_string && (*endp == 'e' || *endp == 'E'))
922   {
923     int str_error;
924     const char *end_of_exponent= end_of_string;
925     longlong exponent= my_strtoll10(endp+1, (char**) &end_of_exponent,
926                                     &str_error);
927 
928     if (end_of_exponent != endp +1)               /* If at least one digit */
929     {
930       *end= (char*) end_of_exponent;
931       if (str_error > 0)
932       {
933         if (str_error == MY_ERRNO_ERANGE)
934         {
935           /*
936             Exponent is:
937             - a huge positive number that does not fit into ulonglong
938             - a huge negative number that does not fit into longlong
939             Skip all remaining digits.
940           */
941           for ( ; end_of_exponent < end_of_string &&
942                   my_isdigit(&my_charset_latin1, *end_of_exponent)
943                 ; end_of_exponent++)
944           { }
945           *end= (char*) end_of_exponent;
946           if (exponent == ~0)
947           {
948             if (!decimal_is_zero(to))
949             {
950               /*
951                 Non-zero mantissa and a huge positive exponent that
952                 does not fit into ulonglong, e.g.:
953                   1e111111111111111111111
954               */
955               error= E_DEC_OVERFLOW;
956             }
957             else
958             {
959               /*
960                 Zero mantissa and a huge positive exponent that
961                 does not fit into ulonglong, e.g.:
962                   0e111111111111111111111
963                 Return zero without warnings.
964               */
965             }
966           }
967           else
968           {
969             /*
970               Huge negative exponent that does not fit into longlong, e.g.
971                 1e-111111111111111111111
972                 0e-111111111111111111111
973               Return zero without warnings.
974             */
975           }
976           goto fatal_error;
977         }
978 
979         /*
980           Some other error, e.g. MY_ERRNO_EDOM
981         */
982         error= E_DEC_BAD_NUM;
983         goto fatal_error;
984       }
985       if (exponent > INT_MAX/2 || (str_error == 0 && exponent < 0))
986       {
987         /*
988           The exponent fits into ulonglong, but it's still huge, e.g.
989             1e1111111111
990         */
991         if (!decimal_is_zero(to))
992           error= E_DEC_OVERFLOW;
993         goto fatal_error;
994       }
995       if (exponent < INT_MIN/2 && error != E_DEC_OVERFLOW)
996       {
997         error= E_DEC_TRUNCATED;
998         goto fatal_error;
999       }
1000       if (error != E_DEC_OVERFLOW)
1001         error= decimal_shift(to, (int) exponent);
1002     }
1003   }
1004   if (to->sign && decimal_is_zero(to))
1005     to->sign= 0;
1006   return error;
1007 
1008 fatal_error:
1009   decimal_make_zero(to);
1010   return error;
1011 }
1012 
1013 
1014 /*
1015   Convert decimal to double
1016 
1017   SYNOPSIS
1018     decimal2double()
1019       from    - value to convert
1020       to      - result will be stored there
1021 
1022   RETURN VALUE
1023     E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1024 */
1025 
decimal2double(const decimal_t * from,double * to)1026 int decimal2double(const decimal_t *from, double *to)
1027 {
1028   char strbuf[FLOATING_POINT_BUFFER], *end;
1029   int len= sizeof(strbuf);
1030   int rc, error;
1031 
1032   rc = decimal2string(from, strbuf, &len, 0, 0, 0);
1033   end= strbuf + len;
1034 
1035   DBUG_PRINT("info", ("interm.: %s", strbuf));
1036 
1037   *to= my_strtod(strbuf, &end, &error);
1038 
1039   DBUG_PRINT("info", ("result: %f", *to));
1040 
1041   return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
1042 }
1043 
1044 /*
1045   Convert double to decimal
1046 
1047   SYNOPSIS
1048     double2decimal()
1049       from    - value to convert
1050       to      - result will be stored there
1051 
1052   RETURN VALUE
1053     E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1054 */
1055 
double2decimal(double from,decimal_t * to)1056 int double2decimal(double from, decimal_t *to)
1057 {
1058   char buff[FLOATING_POINT_BUFFER], *end;
1059   int res;
1060   DBUG_ENTER("double2decimal");
1061   end= buff + my_gcvt(from, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
1062   res= string2decimal(buff, to, &end);
1063   DBUG_PRINT("exit", ("res: %d", res));
1064   DBUG_RETURN(res);
1065 }
1066 
1067 
ull2dec(ulonglong from,decimal_t * to)1068 static int ull2dec(ulonglong from, decimal_t *to)
1069 {
1070   int intg1, error=E_DEC_OK;
1071   ulonglong x=from;
1072   dec1 *buf;
1073 
1074   sanity(to);
1075 
1076   if (!from)
1077   {
1078     decimal_make_zero(to);
1079     return E_DEC_OK;
1080   }
1081 
1082   for (intg1=1; from >= DIG_BASE; intg1++, from/=DIG_BASE) {}
1083   if (unlikely(intg1 > to->len))
1084   {
1085     intg1=to->len;
1086     error=E_DEC_OVERFLOW;
1087   }
1088   to->frac=0;
1089   for(to->intg= (intg1-1)*DIG_PER_DEC1; from; to->intg++, from/=10) {}
1090 
1091   for (buf=to->buf+intg1; intg1; intg1--)
1092   {
1093     ulonglong y=x/DIG_BASE;
1094     *--buf=(dec1)(x-y*DIG_BASE);
1095     x=y;
1096   }
1097   return error;
1098 }
1099 
ulonglong2decimal(ulonglong from,decimal_t * to)1100 int ulonglong2decimal(ulonglong from, decimal_t *to)
1101 {
1102   to->sign=0;
1103   return ull2dec(from, to);
1104 }
1105 
longlong2decimal(longlong from,decimal_t * to)1106 int longlong2decimal(longlong from, decimal_t *to)
1107 {
1108   if ((to->sign= from < 0))
1109   {
1110     if (from == LONGLONG_MIN) // avoid undefined behavior
1111       return ull2dec((ulonglong)LONGLONG_MIN, to);
1112     return ull2dec(-from, to);
1113   }
1114   return ull2dec(from, to);
1115 }
1116 
decimal2ulonglong(const decimal_t * from,ulonglong * to)1117 int decimal2ulonglong(const decimal_t *from, ulonglong *to)
1118 {
1119   dec1 *buf=from->buf;
1120   ulonglong x=0;
1121   int intg, frac;
1122 
1123   if (from->sign)
1124   {
1125       *to= 0;
1126       return E_DEC_OVERFLOW;
1127   }
1128 
1129   for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1130   {
1131     ulonglong y=x;
1132     x=x*DIG_BASE + *buf++;
1133     if (unlikely(y > ((ulonglong) ULONGLONG_MAX/DIG_BASE) || x < y))
1134     {
1135       *to=ULONGLONG_MAX;
1136       return E_DEC_OVERFLOW;
1137     }
1138   }
1139   *to=x;
1140   for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1141     if (*buf++)
1142       return E_DEC_TRUNCATED;
1143   return E_DEC_OK;
1144 }
1145 
decimal2longlong(const decimal_t * from,longlong * to)1146 int decimal2longlong(const decimal_t *from, longlong *to)
1147 {
1148   dec1 *buf=from->buf;
1149   longlong x=0;
1150   int intg, frac;
1151 
1152   for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1153   {
1154     longlong y=x;
1155     /*
1156       Attention: trick!
1157       we're calculating -|from| instead of |from| here
1158       because |LONGLONG_MIN| > LONGLONG_MAX
1159       so we can convert -9223372036854775808 correctly
1160     */
1161     x=x*DIG_BASE - *buf++;
1162     if (unlikely(y < (LONGLONG_MIN/DIG_BASE) || x > y))
1163     {
1164       /*
1165         the decimal is bigger than any possible integer
1166         return border integer depending on the sign
1167       */
1168       *to= from->sign ? LONGLONG_MIN : LONGLONG_MAX;
1169       return E_DEC_OVERFLOW;
1170     }
1171   }
1172   /* boundary case: 9223372036854775808 */
1173   if (unlikely(from->sign==0 && x == LONGLONG_MIN))
1174   {
1175     *to= LONGLONG_MAX;
1176     return E_DEC_OVERFLOW;
1177   }
1178 
1179   *to=from->sign ? x : -x;
1180   for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1181     if (*buf++)
1182       return E_DEC_TRUNCATED;
1183   return E_DEC_OK;
1184 }
1185 
1186 /*
1187   Convert decimal to its binary fixed-length representation
1188   two representations of the same length can be compared with memcmp
1189   with the correct -1/0/+1 result
1190 
1191   SYNOPSIS
1192     decimal2bin()
1193       from    - value to convert
1194       to      - points to buffer where string representation should be stored
1195       precision/scale - see decimal_bin_size() below
1196 
1197   NOTE
1198     the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1199 
1200   RETURN VALUE
1201     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1202 
1203   DESCRIPTION
1204     for storage decimal numbers are converted to the "binary" format.
1205 
1206     This format has the following properties:
1207       1. length of the binary representation depends on the {precision, scale}
1208       as provided by the caller and NOT on the intg/frac of the decimal to
1209       convert.
1210       2. binary representations of the same {precision, scale} can be compared
1211       with memcmp - with the same result as decimal_cmp() of the original
1212       decimals (not taking into account possible precision loss during
1213       conversion).
1214 
1215     This binary format is as follows:
1216       1. First the number is converted to have a requested precision and scale.
1217       2. Every full DIG_PER_DEC1 digits of intg part are stored in 4 bytes
1218          as is
1219       3. The first intg % DIG_PER_DEC1 digits are stored in the reduced
1220          number of bytes (enough bytes to store this number of digits -
1221          see dig2bytes)
1222       4. same for frac - full decimal_digit_t's are stored as is,
1223          the last frac % DIG_PER_DEC1 digits - in the reduced number of bytes.
1224       5. If the number is negative - every byte is inversed.
1225       5. The very first bit of the resulting byte array is inverted (because
1226          memcmp compares unsigned bytes, see property 2 above)
1227 
1228     Example:
1229 
1230       1234567890.1234
1231 
1232     internally is represented as 3 decimal_digit_t's
1233 
1234       1 234567890 123400000
1235 
1236     (assuming we want a binary representation with precision=14, scale=4)
1237     in hex it's
1238 
1239       00-00-00-01  0D-FB-38-D2  07-5A-EF-40
1240 
1241     now, middle decimal_digit_t is full - it stores 9 decimal digits. It goes
1242     into binary representation as is:
1243 
1244 
1245       ...........  0D-FB-38-D2 ............
1246 
1247     First decimal_digit_t has only one decimal digit. We can store one digit in
1248     one byte, no need to waste four:
1249 
1250                 01 0D-FB-38-D2 ............
1251 
1252     now, last digit. It's 123400000. We can store 1234 in two bytes:
1253 
1254                 01 0D-FB-38-D2 04-D2
1255 
1256     So, we've packed 12 bytes number in 7 bytes.
1257     And now we invert the highest bit to get the final result:
1258 
1259                 81 0D FB 38 D2 04 D2
1260 
1261     And for -1234567890.1234 it would be
1262 
1263                 7E F2 04 C7 2D FB 2D
1264 */
decimal2bin(const decimal_t * from,uchar * to,int precision,int frac)1265 int decimal2bin(const decimal_t *from, uchar *to, int precision, int frac)
1266 {
1267   dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
1268   int error=E_DEC_OK, intg=precision-frac,
1269       isize1, intg1, intg1x, from_intg,
1270       intg0=intg/DIG_PER_DEC1,
1271       frac0=frac/DIG_PER_DEC1,
1272       intg0x=intg-intg0*DIG_PER_DEC1,
1273       frac0x=frac-frac0*DIG_PER_DEC1,
1274       frac1=from->frac/DIG_PER_DEC1,
1275       frac1x=from->frac-frac1*DIG_PER_DEC1,
1276       isize0=intg0*sizeof(dec1)+dig2bytes[intg0x],
1277       fsize0=frac0*sizeof(dec1)+dig2bytes[frac0x],
1278       fsize1=frac1*sizeof(dec1)+dig2bytes[frac1x];
1279   const int orig_isize0= isize0;
1280   const int orig_fsize0= fsize0;
1281   uchar *orig_to= to;
1282 
1283   buf1= remove_leading_zeroes(from, &from_intg);
1284 
1285   if (unlikely(from_intg+fsize1==0))
1286   {
1287     mask=0; /* just in case */
1288     intg=1;
1289     buf1=&mask;
1290   }
1291 
1292   intg1=from_intg/DIG_PER_DEC1;
1293   intg1x=from_intg-intg1*DIG_PER_DEC1;
1294   isize1=intg1*sizeof(dec1)+dig2bytes[intg1x];
1295 
1296   if (intg < from_intg)
1297   {
1298     buf1+=intg1-intg0+(intg1x>0)-(intg0x>0);
1299     intg1=intg0; intg1x=intg0x;
1300     error=E_DEC_OVERFLOW;
1301   }
1302   else if (isize0 > isize1)
1303   {
1304     while (isize0-- > isize1)
1305       *to++= (char)mask;
1306   }
1307   if (fsize0 < fsize1)
1308   {
1309     frac1=frac0; frac1x=frac0x;
1310     error=E_DEC_TRUNCATED;
1311   }
1312   else if (fsize0 > fsize1 && frac1x)
1313   {
1314     if (frac0 == frac1)
1315     {
1316       frac1x=frac0x;
1317       fsize0= fsize1;
1318     }
1319     else
1320     {
1321       frac1++;
1322       frac1x=0;
1323     }
1324   }
1325 
1326   /* intg1x part */
1327   if (intg1x)
1328   {
1329     int i=dig2bytes[intg1x];
1330     dec1 x=(*buf1++ % powers10[intg1x]) ^ mask;
1331     switch (i)
1332     {
1333       case 1: mi_int1store(to, x); break;
1334       case 2: mi_int2store(to, x); break;
1335       case 3: mi_int3store(to, x); break;
1336       case 4: mi_int4store(to, x); break;
1337       default: DBUG_ASSERT(0);
1338     }
1339     to+=i;
1340   }
1341 
1342   /* intg1+frac1 part */
1343   for (stop1=buf1+intg1+frac1; buf1 < stop1; to+=sizeof(dec1))
1344   {
1345     dec1 x=*buf1++ ^ mask;
1346     DBUG_ASSERT(sizeof(dec1) == 4);
1347     mi_int4store(to, x);
1348   }
1349 
1350   /* frac1x part */
1351   if (frac1x)
1352   {
1353     dec1 x;
1354     int i=dig2bytes[frac1x],
1355         lim=(frac1 < frac0 ? DIG_PER_DEC1 : frac0x);
1356     while (frac1x < lim && dig2bytes[frac1x] == i)
1357       frac1x++;
1358     x=(*buf1 / powers10[DIG_PER_DEC1 - frac1x]) ^ mask;
1359     switch (i)
1360     {
1361       case 1: mi_int1store(to, x); break;
1362       case 2: mi_int2store(to, x); break;
1363       case 3: mi_int3store(to, x); break;
1364       case 4: mi_int4store(to, x); break;
1365       default: DBUG_ASSERT(0);
1366     }
1367     to+=i;
1368   }
1369   if (fsize0 > fsize1)
1370   {
1371     uchar *to_end= orig_to + orig_fsize0 + orig_isize0;
1372 
1373     while (fsize0-- > fsize1 && to < to_end)
1374       *to++= (uchar)mask;
1375   }
1376   orig_to[0]^= 0x80;
1377 
1378   /* Check that we have written the whole decimal and nothing more */
1379   DBUG_ASSERT(to == orig_to + orig_fsize0 + orig_isize0);
1380   return error;
1381 }
1382 
1383 /*
1384   Restores decimal from its binary fixed-length representation
1385 
1386   SYNOPSIS
1387     bin2decimal()
1388       from    - value to convert
1389       to      - result
1390       precision/scale - see decimal_bin_size() below
1391 
1392   NOTE
1393     see decimal2bin()
1394     the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1395 
1396   RETURN VALUE
1397     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1398 */
1399 
bin2decimal(const uchar * from,decimal_t * to,int precision,int scale)1400 int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale)
1401 {
1402   int error=E_DEC_OK, intg=precision-scale,
1403       intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1404       intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1,
1405       intg1=intg0+(intg0x>0), frac1=frac0+(frac0x>0);
1406   dec1 *buf=to->buf, mask=(*from & 0x80) ? 0 : -1;
1407   const uchar *stop;
1408   uchar *d_copy;
1409   int bin_size= decimal_bin_size(precision, scale);
1410 
1411   sanity(to);
1412   d_copy= (uchar*) my_alloca(bin_size);
1413   memcpy(d_copy, from, bin_size);
1414   d_copy[0]^= 0x80;
1415   from= d_copy;
1416 
1417   FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
1418   if (unlikely(error))
1419   {
1420     if (intg1 < intg0+(intg0x>0))
1421     {
1422       from+=dig2bytes[intg0x]+sizeof(dec1)*(intg0-intg1);
1423       frac0=frac0x=intg0x=0;
1424       intg0=intg1;
1425     }
1426     else
1427     {
1428       frac0x=0;
1429       frac0=frac1;
1430     }
1431   }
1432 
1433   to->sign=(mask != 0);
1434   to->intg=intg0*DIG_PER_DEC1+intg0x;
1435   to->frac=frac0*DIG_PER_DEC1+frac0x;
1436 
1437   if (intg0x)
1438   {
1439     int i=dig2bytes[intg0x];
1440     dec1 UNINIT_VAR(x);
1441     switch (i)
1442     {
1443       case 1: x=mi_sint1korr(from); break;
1444       case 2: x=mi_sint2korr(from); break;
1445       case 3: x=mi_sint3korr(from); break;
1446       case 4: x=mi_sint4korr(from); break;
1447       default: abort();
1448     }
1449     from+=i;
1450     *buf=x ^ mask;
1451     if (((ulonglong)*buf) >= (ulonglong) powers10[intg0x+1])
1452       goto err;
1453     if (buf > to->buf || *buf != 0)
1454       buf++;
1455     else
1456       to->intg-=intg0x;
1457   }
1458   for (stop=from+intg0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1459   {
1460     DBUG_ASSERT(sizeof(dec1) == 4);
1461     *buf=mi_sint4korr(from) ^ mask;
1462     if (((uint32)*buf) > DIG_MAX)
1463       goto err;
1464     if (buf > to->buf || *buf != 0)
1465       buf++;
1466     else
1467       to->intg-=DIG_PER_DEC1;
1468   }
1469   DBUG_ASSERT(to->intg >=0);
1470   for (stop=from+frac0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1471   {
1472     DBUG_ASSERT(sizeof(dec1) == 4);
1473     *buf=mi_sint4korr(from) ^ mask;
1474     if (((uint32)*buf) > DIG_MAX)
1475       goto err;
1476     buf++;
1477   }
1478   if (frac0x)
1479   {
1480     int i=dig2bytes[frac0x];
1481     dec1 UNINIT_VAR(x);
1482     switch (i)
1483     {
1484       case 1: x=mi_sint1korr(from); break;
1485       case 2: x=mi_sint2korr(from); break;
1486       case 3: x=mi_sint3korr(from); break;
1487       case 4: x=mi_sint4korr(from); break;
1488       default: abort();
1489     }
1490     *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
1491     if (((uint32)*buf) > DIG_MAX)
1492       goto err;
1493     buf++;
1494   }
1495   my_afree(d_copy);
1496 
1497   /*
1498     No digits? We have read the number zero, of unspecified precision.
1499     Make it a proper zero, with non-zero precision.
1500   */
1501   if (to->intg == 0 && to->frac == 0)
1502     decimal_make_zero(to);
1503   return error;
1504 
1505 err:
1506   my_afree(d_copy);
1507   decimal_make_zero(to);
1508   return(E_DEC_BAD_NUM);
1509 }
1510 
1511 /*
1512   Returns the size of array to hold a decimal with given precision and scale
1513 
1514   RETURN VALUE
1515     size in dec1
1516     (multiply by sizeof(dec1) to get the size if bytes)
1517 */
1518 
decimal_size(int precision,int scale)1519 int decimal_size(int precision, int scale)
1520 {
1521   DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
1522   return ROUND_UP(precision-scale)+ROUND_UP(scale);
1523 }
1524 
1525 /*
1526   Returns the size of array to hold a binary representation of a decimal
1527 
1528   RETURN VALUE
1529     size in bytes
1530 */
1531 
decimal_bin_size(int precision,int scale)1532 int decimal_bin_size(int precision, int scale)
1533 {
1534   int intg=precision-scale,
1535       intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1536       intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1;
1537 
1538   DBUG_ASSERT(scale >= 0);
1539   DBUG_ASSERT(precision > 0);
1540   DBUG_ASSERT(scale <= precision);
1541   return intg0*sizeof(dec1)+dig2bytes[intg0x]+
1542          frac0*sizeof(dec1)+dig2bytes[frac0x];
1543 }
1544 
1545 /*
1546   Rounds the decimal to "scale" digits
1547 
1548   SYNOPSIS
1549     decimal_round()
1550       from    - decimal to round,
1551       to      - result buffer. from==to is allowed
1552       scale   - to what position to round. can be negative!
1553       mode    - round to nearest even or truncate
1554 
1555   NOTES
1556     scale can be negative !
1557     one TRUNCATED error (line XXX below) isn't treated very logical :(
1558 
1559   RETURN VALUE
1560     E_DEC_OK/E_DEC_TRUNCATED
1561 */
1562 
1563 int
decimal_round(const decimal_t * from,decimal_t * to,int scale,decimal_round_mode mode)1564 decimal_round(const decimal_t *from, decimal_t *to, int scale,
1565               decimal_round_mode mode)
1566 {
1567   int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
1568     frac1=ROUND_UP(from->frac), UNINIT_VAR(round_digit),
1569     intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len;
1570 
1571   dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
1572   int first_dig;
1573 
1574   sanity(to);
1575 
1576   switch (mode) {
1577   case HALF_UP:
1578   case HALF_EVEN:       round_digit=5; break;
1579   case CEILING:         round_digit= from->sign ? 10 : 0; break;
1580   case FLOOR:           round_digit= from->sign ? 0 : 10; break;
1581   case TRUNCATE:        round_digit=10; break;
1582   default: DBUG_ASSERT(0);
1583   }
1584 
1585   /*
1586     For my_decimal we always use len == DECIMAL_BUFF_LENGTH == 9
1587     For internal testing here (ifdef MAIN) we always use len == 100/4
1588    */
1589   DBUG_ASSERT(from->len == to->len);
1590 
1591   if (unlikely(frac0+intg0 > len))
1592   {
1593     frac0=len-intg0;
1594     scale=frac0*DIG_PER_DEC1;
1595     error=E_DEC_TRUNCATED;
1596   }
1597 
1598   if (scale+from->intg < 0)
1599   {
1600     decimal_make_zero(to);
1601     return E_DEC_OK;
1602   }
1603 
1604   if (to != from)
1605   {
1606     dec1 *p0= buf0+intg0+MY_MAX(frac1, frac0);
1607     dec1 *p1= buf1+intg0+MY_MAX(frac1, frac0);
1608 
1609     DBUG_ASSERT(p0 - buf0 <= len);
1610     DBUG_ASSERT(p1 - buf1 <= len);
1611 
1612     while (buf0 < p0)
1613       *(--p1) = *(--p0);
1614 
1615     buf0=to->buf;
1616     buf1=to->buf;
1617     to->sign=from->sign;
1618     to->intg=MY_MIN(intg0, len)*DIG_PER_DEC1;
1619   }
1620 
1621   if (frac0 > frac1)
1622   {
1623     buf1+=intg0+frac1;
1624     while (frac0-- > frac1)
1625       *buf1++=0;
1626     goto done;
1627   }
1628 
1629   if (scale >= from->frac)
1630     goto done; /* nothing to do */
1631 
1632   buf0+=intg0+frac0-1;
1633   buf1+=intg0+frac0-1;
1634   if (scale == frac0*DIG_PER_DEC1)
1635   {
1636     int do_inc= FALSE;
1637     DBUG_ASSERT(frac0+intg0 >= 0);
1638     switch (round_digit) {
1639     case 0:
1640     {
1641       dec1 *p0= buf0 + (frac1-frac0);
1642       for (; p0 > buf0; p0--)
1643       {
1644         if (*p0)
1645         {
1646           do_inc= TRUE;
1647           break;
1648         }
1649       }
1650       break;
1651     }
1652     case 5:
1653     {
1654       x= buf0[1]/DIG_MASK;
1655       do_inc= (x>5) || ((x == 5) &&
1656                         (mode == HALF_UP || (frac0+intg0 > 0 && *buf0 & 1)));
1657       break;
1658     }
1659     default:
1660       break;
1661     }
1662     if (do_inc)
1663     {
1664       if (frac0+intg0>0)
1665         (*buf1)++;
1666       else
1667         *(++buf1)=DIG_BASE;
1668     }
1669     else if (frac0+intg0==0)
1670     {
1671       decimal_make_zero(to);
1672       return E_DEC_OK;
1673     }
1674   }
1675   else
1676   {
1677     /* TODO - fix this code as it won't work for CEILING mode */
1678     int pos=frac0*DIG_PER_DEC1-scale-1;
1679     DBUG_ASSERT(frac0+intg0 > 0);
1680     x=*buf1 / powers10[pos];
1681     y=x % 10;
1682     if (y > round_digit ||
1683         (round_digit == 5 && y == 5 && (mode == HALF_UP || (x/10) & 1)))
1684       x+=10;
1685     *buf1=powers10[pos]*(x-y);
1686   }
1687   if (*buf1 >= DIG_BASE)
1688   {
1689     carry=1;
1690     *buf1-=DIG_BASE;
1691     while (carry && --buf1 >= to->buf)
1692       ADD(*buf1, *buf1, 0, carry);
1693     if (unlikely(carry))
1694     {
1695       /* shifting the number to create space for new digit */
1696       if (frac0+intg0 >= len)
1697       {
1698         frac0--;
1699         scale=frac0*DIG_PER_DEC1;
1700         error=E_DEC_TRUNCATED; /* XXX */
1701       }
1702       for (buf1=to->buf+intg0+MY_MAX(frac0,0); buf1 > to->buf; buf1--)
1703       {
1704         buf1[0]=buf1[-1];
1705       }
1706       *buf1=1;
1707       to->intg++;
1708       intg0++;
1709     }
1710   }
1711   else
1712   {
1713     for (;;)
1714     {
1715       if (likely(*buf1))
1716         break;
1717       if (buf1-- == to->buf)
1718       {
1719         /* making 'zero' with the proper scale */
1720         dec1 *p0= to->buf + frac0 + 1;
1721         to->intg=1;
1722         to->frac= MY_MAX(scale, 0);
1723         to->sign= 0;
1724         for (buf1= to->buf; buf1<p0; buf1++)
1725           *buf1= 0;
1726         return E_DEC_OK;
1727       }
1728     }
1729   }
1730   /*
1731     In case we're rounding e.g. 1.5e9 to 2.0e9, the decimal_digit_t's inside
1732     the buffer are as follows.
1733 
1734     Before <1, 5e8>
1735     After  <2, 5e8>
1736 
1737     Hence we need to set the 2nd field to 0.
1738     The same holds if we round 1.5e-9 to 2e-9.
1739    */
1740   if (frac0 < frac1)
1741   {
1742     dec1 *buf= to->buf + ((scale == 0 && intg0 == 0) ? 1 : intg0 + frac0);
1743     dec1 *end= to->buf + len;
1744 
1745     while (buf < end)
1746       *buf++=0;
1747   }
1748 
1749   /* Here we  check 999.9 -> 1000 case when we need to increase intg */
1750   first_dig= to->intg % DIG_PER_DEC1;
1751   if (first_dig && (*buf1 >= powers10[first_dig]))
1752     to->intg++;
1753 
1754   if (scale<0)
1755     scale=0;
1756 
1757 done:
1758   to->frac=scale;
1759   return error;
1760 }
1761 
1762 /*
1763   Returns the size of the result of the operation
1764 
1765   SYNOPSIS
1766     decimal_result_size()
1767       from1   - operand of the unary operation or first operand of the
1768                 binary operation
1769       from2   - second operand of the binary operation
1770       op      - operation. one char '+', '-', '*', '/' are allowed
1771                 others may be added later
1772       param   - extra param to the operation. unused for '+', '-', '*'
1773                 scale increment for '/'
1774 
1775   NOTE
1776     returned valued may be larger than the actual buffer required
1777     in the operation, as decimal_result_size, by design, operates on
1778     precision/scale values only and not on the actual decimal number
1779 
1780   RETURN VALUE
1781     size of to->buf array in dec1 elements. to get size in bytes
1782     multiply by sizeof(dec1)
1783 */
1784 
decimal_result_size(decimal_t * from1,decimal_t * from2,char op,int param)1785 int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, int param)
1786 {
1787   switch (op) {
1788   case '-':
1789     return ROUND_UP(MY_MAX(from1->intg, from2->intg)) +
1790            ROUND_UP(MY_MAX(from1->frac, from2->frac));
1791   case '+':
1792     return ROUND_UP(MY_MAX(from1->intg, from2->intg)+1) +
1793            ROUND_UP(MY_MAX(from1->frac, from2->frac));
1794   case '*':
1795     return ROUND_UP(from1->intg+from2->intg)+
1796            ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
1797   case '/':
1798     return ROUND_UP(from1->intg+from2->intg+1+from1->frac+from2->frac+param);
1799   default: DBUG_ASSERT(0);
1800   }
1801   return -1; /* shut up the warning */
1802 }
1803 
do_add(const decimal_t * from1,const decimal_t * from2,decimal_t * to)1804 static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1805 {
1806   int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1807       frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1808       frac0=MY_MAX(frac1, frac2), intg0=MY_MAX(intg1, intg2), error;
1809   dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
1810 
1811   sanity(to);
1812 
1813   /* is there a need for extra word because of carry ? */
1814   x=intg1 > intg2 ? from1->buf[0] :
1815     intg2 > intg1 ? from2->buf[0] :
1816     from1->buf[0] + from2->buf[0] ;
1817   if (unlikely(x > DIG_MAX-1)) /* yes, there is */
1818   {
1819     intg0++;
1820     to->buf[0]=0; /* safety */
1821   }
1822 
1823   FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
1824   if (unlikely(error == E_DEC_OVERFLOW))
1825   {
1826     max_decimal(to->len * DIG_PER_DEC1, 0, to);
1827     return error;
1828   }
1829 
1830   buf0=to->buf+intg0+frac0;
1831 
1832   to->sign=from1->sign;
1833   to->frac=MY_MAX(from1->frac, from2->frac);
1834   to->intg=intg0*DIG_PER_DEC1;
1835   if (unlikely(error))
1836   {
1837     set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
1838     set_if_smaller(frac1, frac0);
1839     set_if_smaller(frac2, frac0);
1840     set_if_smaller(intg1, intg0);
1841     set_if_smaller(intg2, intg0);
1842   }
1843 
1844   /* part 1 - MY_MAX(frac) ... min (frac) */
1845   if (frac1 > frac2)
1846   {
1847     buf1=from1->buf+intg1+frac1;
1848     stop=from1->buf+intg1+frac2;
1849     buf2=from2->buf+intg2+frac2;
1850     stop2=from1->buf+(intg1 > intg2 ? intg1-intg2 : 0);
1851   }
1852   else
1853   {
1854     buf1=from2->buf+intg2+frac2;
1855     stop=from2->buf+intg2+frac1;
1856     buf2=from1->buf+intg1+frac1;
1857     stop2=from2->buf+(intg2 > intg1 ? intg2-intg1 : 0);
1858   }
1859   while (buf1 > stop)
1860     *--buf0=*--buf1;
1861 
1862   /* part 2 - MY_MIN(frac) ... MY_MIN(intg) */
1863   carry=0;
1864   while (buf1 > stop2)
1865   {
1866     ADD(*--buf0, *--buf1, *--buf2, carry);
1867   }
1868 
1869   /* part 3 - MY_MIN(intg) ... MY_MAX(intg) */
1870   buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
1871                         ((stop=from2->buf)+intg2-intg1) ;
1872   while (buf1 > stop)
1873   {
1874     ADD(*--buf0, *--buf1, 0, carry);
1875   }
1876 
1877   if (unlikely(carry))
1878     *--buf0=1;
1879   DBUG_ASSERT(buf0 == to->buf || buf0 == to->buf+1);
1880 
1881   return error;
1882 }
1883 
1884 /* to=from1-from2.
1885    if to==0, return -1/0/+1 - the result of the comparison */
do_sub(const decimal_t * from1,const decimal_t * from2,decimal_t * to)1886 static int do_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1887 {
1888   int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1889       frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
1890   int frac0=MY_MAX(frac1, frac2), error;
1891   dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2;
1892   my_bool carry=0;
1893 
1894   /* let carry:=1 if from2 > from1 */
1895   start1=buf1=from1->buf; stop1=buf1+intg1;
1896   start2=buf2=from2->buf; stop2=buf2+intg2;
1897   if (unlikely(*buf1 == 0))
1898   {
1899     while (buf1 < stop1 && *buf1 == 0)
1900       buf1++;
1901     start1=buf1;
1902     intg1= (int) (stop1-buf1);
1903   }
1904   if (unlikely(*buf2 == 0))
1905   {
1906     while (buf2 < stop2 && *buf2 == 0)
1907       buf2++;
1908     start2=buf2;
1909     intg2= (int) (stop2-buf2);
1910   }
1911   if (intg2 > intg1)
1912     carry=1;
1913   else if (intg2 == intg1)
1914   {
1915     dec1 *end1= stop1 + (frac1 - 1);
1916     dec1 *end2= stop2 + (frac2 - 1);
1917     while (unlikely((buf1 <= end1) && (*end1 == 0)))
1918       end1--;
1919     while (unlikely((buf2 <= end2) && (*end2 == 0)))
1920       end2--;
1921     frac1= (int) (end1 - stop1) + 1;
1922     frac2= (int) (end2 - stop2) + 1;
1923     while (buf1 <=end1 && buf2 <= end2 && *buf1 == *buf2)
1924       buf1++, buf2++;
1925     if (buf1 <= end1)
1926     {
1927       if (buf2 <= end2)
1928         carry= *buf2 > *buf1;
1929       else
1930         carry= 0;
1931     }
1932     else
1933     {
1934       if (buf2 <= end2)
1935         carry=1;
1936       else /* short-circuit everything: from1 == from2 */
1937       {
1938         if (to == 0) /* decimal_cmp() */
1939           return 0;
1940         decimal_make_zero(to);
1941         return E_DEC_OK;
1942       }
1943     }
1944   }
1945 
1946   if (to == 0) /* decimal_cmp() */
1947     return carry == from1->sign ? 1 : -1;
1948 
1949   sanity(to);
1950 
1951   to->sign=from1->sign;
1952 
1953   /* ensure that always from1 > from2 (and intg1 >= intg2) */
1954   if (carry)
1955   {
1956     swap_variables(const decimal_t *, from1, from2);
1957     swap_variables(dec1 *,start1, start2);
1958     swap_variables(int,intg1,intg2);
1959     swap_variables(int,frac1,frac2);
1960     to->sign= !to->sign;
1961   }
1962 
1963   FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
1964   buf0=to->buf+intg1+frac0;
1965 
1966   to->frac=MY_MAX(from1->frac, from2->frac);
1967   to->intg=intg1*DIG_PER_DEC1;
1968   if (unlikely(error))
1969   {
1970     set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
1971     set_if_smaller(frac1, frac0);
1972     set_if_smaller(frac2, frac0);
1973     set_if_smaller(intg2, intg1);
1974   }
1975   carry=0;
1976 
1977   /* part 1 - MY_MAX(frac) ... min (frac) */
1978   if (frac1 > frac2)
1979   {
1980     buf1=start1+intg1+frac1;
1981     stop1=start1+intg1+frac2;
1982     buf2=start2+intg2+frac2;
1983     while (frac0-- > frac1)
1984       *--buf0=0;
1985     while (buf1 > stop1)
1986       *--buf0=*--buf1;
1987   }
1988   else
1989   {
1990     buf1=start1+intg1+frac1;
1991     buf2=start2+intg2+frac2;
1992     stop2=start2+intg2+frac1;
1993     while (frac0-- > frac2)
1994       *--buf0=0;
1995     while (buf2 > stop2)
1996     {
1997       SUB(*--buf0, 0, *--buf2, carry);
1998     }
1999   }
2000 
2001   /* part 2 - MY_MIN(frac) ... intg2 */
2002   while (buf2 > start2)
2003   {
2004     SUB(*--buf0, *--buf1, *--buf2, carry);
2005   }
2006 
2007   /* part 3 - intg2 ... intg1 */
2008   while (carry && buf1 > start1)
2009   {
2010     SUB(*--buf0, *--buf1, 0, carry);
2011   }
2012 
2013   while (buf1 > start1)
2014     *--buf0=*--buf1;
2015 
2016   while (buf0 > to->buf)
2017     *--buf0=0;
2018 
2019   return error;
2020 }
2021 
decimal_intg(const decimal_t * from)2022 int decimal_intg(const decimal_t *from)
2023 {
2024   int res;
2025   remove_leading_zeroes(from, &res);
2026   return res;
2027 }
2028 
decimal_add(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2029 int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2030 {
2031   if (likely(from1->sign == from2->sign))
2032     return do_add(from1, from2, to);
2033   return do_sub(from1, from2, to);
2034 }
2035 
decimal_sub(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2036 int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2037 {
2038   if (likely(from1->sign == from2->sign))
2039     return do_sub(from1, from2, to);
2040   return do_add(from1, from2, to);
2041 }
2042 
decimal_cmp(const decimal_t * from1,const decimal_t * from2)2043 int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
2044 {
2045   if (likely(from1->sign == from2->sign))
2046     return do_sub(from1, from2, 0);
2047   return from1->sign > from2->sign ? -1 : 1;
2048 }
2049 
decimal_is_zero(const decimal_t * from)2050 int decimal_is_zero(const decimal_t *from)
2051 {
2052   dec1 *buf1=from->buf,
2053        *end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
2054   while (buf1 < end)
2055     if (*buf1++)
2056       return 0;
2057   return 1;
2058 }
2059 
2060 /*
2061   multiply two decimals
2062 
2063   SYNOPSIS
2064     decimal_mul()
2065       from1, from2 - factors
2066       to      - product
2067 
2068   RETURN VALUE
2069     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW;
2070 
2071   NOTES
2072     in this implementation, with sizeof(dec1)=4 we have DIG_PER_DEC1=9,
2073     and 63-digit number will take only 7 dec1 words (basically a 7-digit
2074     "base 999999999" number).  Thus there's no need in fast multiplication
2075     algorithms, 7-digit numbers can be multiplied with a naive O(n*n)
2076     method.
2077 
2078     XXX if this library is to be used with huge numbers of thousands of
2079     digits, fast multiplication must be implemented.
2080 */
decimal_mul(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2081 int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2082 {
2083   int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
2084       frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
2085       intg0=ROUND_UP(from1->intg+from2->intg),
2086       frac0=frac1+frac2, error, i, j, d_to_move;
2087   dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
2088        *start2, *stop2, *stop1, *start0, carry;
2089 
2090   sanity(to);
2091 
2092   i=intg0;                                       /* save 'ideal' values */
2093   j=frac0;
2094   FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);  /* bound size */
2095   to->sign=from1->sign != from2->sign;
2096   to->frac=from1->frac+from2->frac;              /* store size in digits */
2097   to->intg=intg0*DIG_PER_DEC1;
2098 
2099   if (unlikely(error))
2100   {
2101     set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
2102     set_if_smaller(to->intg, intg0*DIG_PER_DEC1);
2103     if (unlikely(i > intg0))                     /* bounded integer-part */
2104     {
2105       i-=intg0;
2106       j=i >> 1;
2107       intg1-= j;
2108       intg2-=i-j;
2109       frac1=frac2=0; /* frac0 is already 0 here */
2110     }
2111     else                                         /* bounded fract part */
2112     {
2113       j-=frac0;
2114       i=j >> 1;
2115       if (frac1 <= frac2)
2116       {
2117         frac1-= i;
2118         frac2-=j-i;
2119       }
2120       else
2121       {
2122         frac2-= i;
2123         frac1-=j-i;
2124       }
2125     }
2126   }
2127   start0=to->buf+intg0+frac0-1;
2128   start2=buf2+frac2-1;
2129   stop1=buf1-intg1;
2130   stop2=buf2-intg2;
2131 
2132   bzero(to->buf, (intg0+frac0)*sizeof(dec1));
2133 
2134   for (buf1+=frac1-1; buf1 >= stop1; buf1--, start0--)
2135   {
2136     carry=0;
2137     for (buf0=start0, buf2=start2; buf2 >= stop2; buf2--, buf0--)
2138     {
2139       dec1 hi, lo;
2140       dec2 p= ((dec2)*buf1) * ((dec2)*buf2);
2141       hi=(dec1)(p/DIG_BASE);
2142       lo=(dec1)(p-((dec2)hi)*DIG_BASE);
2143       ADD2(*buf0, *buf0, lo, carry);
2144       carry+=hi;
2145     }
2146     if (carry)
2147     {
2148       if (buf0 < to->buf)
2149         return E_DEC_OVERFLOW;
2150       ADD2(*buf0, *buf0, 0, carry);
2151     }
2152     for (buf0--; carry; buf0--)
2153     {
2154       if (buf0 < to->buf)
2155         return E_DEC_OVERFLOW;
2156       ADD(*buf0, *buf0, 0, carry);
2157     }
2158   }
2159 
2160   /* Remove trailing zero words in frac part */
2161   frac0= ROUND_UP(to->frac);
2162 
2163   if (frac0 > 0 && to->buf[intg0 + frac0 - 1] == 0)
2164   {
2165     do
2166     {
2167       frac0--;
2168     } while (frac0 > 0 && to->buf[intg0 + frac0 - 1] == 0);
2169     to->frac= DIG_PER_DEC1 * frac0;
2170   }
2171 
2172   /* Remove heading zero words in intg part */
2173   buf1= to->buf;
2174   d_to_move= intg0 + frac0;
2175   while (!*buf1 && (to->intg > DIG_PER_DEC1))
2176   {
2177     buf1++;
2178     to->intg-= DIG_PER_DEC1;
2179     d_to_move--;
2180   }
2181   if (to->buf < buf1)
2182   {
2183     dec1 *cur_d= to->buf;
2184     for (; d_to_move--; cur_d++, buf1++)
2185       *cur_d= *buf1;
2186   }
2187 
2188   /* Now we have to check for -0.000 case */
2189   if (to->sign && to->frac == 0 && to->buf[0] == 0)
2190   {
2191     DBUG_ASSERT(to->intg <= DIG_PER_DEC1);
2192     /* We got decimal zero */
2193     decimal_make_zero(to);
2194   }
2195   return error;
2196 }
2197 
2198 /*
2199   naive division algorithm (Knuth's Algorithm D in 4.3.1) -
2200   it's ok for short numbers
2201   also we're using alloca() to allocate a temporary buffer
2202 
2203   XXX if this library is to be used with huge numbers of thousands of
2204   digits, fast division must be implemented and alloca should be
2205   changed to malloc (or at least fallback to malloc if alloca() fails)
2206   but then, decimal_mul() should be rewritten too :(
2207 */
do_div_mod(const decimal_t * from1,const decimal_t * from2,decimal_t * to,decimal_t * mod,int scale_incr)2208 static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
2209                       decimal_t *to, decimal_t *mod, int scale_incr)
2210 {
2211   int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2212       frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2213       UNINIT_VAR(error), i, intg0, frac0, len1, len2, dintg, div_mod=(!mod);
2214   dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1,
2215        *start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry;
2216   dec2 norm_factor, x, guess, y;
2217 
2218   if (mod)
2219     to=mod;
2220 
2221   sanity(to);
2222 
2223   /* removing all the leading zeroes */
2224   i= ((prec2 - 1) % DIG_PER_DEC1) + 1;
2225   while (prec2 > 0 && *buf2 == 0)
2226   {
2227     prec2-= i;
2228     i= DIG_PER_DEC1;
2229     buf2++;
2230   }
2231   if (prec2 <= 0) /* short-circuit everything: from2 == 0 */
2232     return E_DEC_DIV_ZERO;
2233   for (i= (prec2 - 1) % DIG_PER_DEC1; *buf2 < powers10[i--]; prec2--) ;
2234   DBUG_ASSERT(prec2 > 0);
2235 
2236   i=((prec1-1) % DIG_PER_DEC1)+1;
2237   while (prec1 > 0 && *buf1 == 0)
2238   {
2239     prec1-=i;
2240     i=DIG_PER_DEC1;
2241     buf1++;
2242   }
2243   if (prec1 <= 0)
2244   { /* short-circuit everything: from1 == 0 */
2245     decimal_make_zero(to);
2246     return E_DEC_OK;
2247   }
2248   for (i=(prec1-1) % DIG_PER_DEC1; *buf1 < powers10[i--]; prec1--) ;
2249   DBUG_ASSERT(prec1 > 0);
2250 
2251   /* let's fix scale_incr, taking into account frac1,frac2 increase */
2252   if ((scale_incr-= frac1 - from1->frac + frac2 - from2->frac) < 0)
2253     scale_incr=0;
2254 
2255   dintg=(prec1-frac1)-(prec2-frac2)+(*buf1 >= *buf2);
2256   if (dintg < 0)
2257   {
2258     dintg/=DIG_PER_DEC1;
2259     intg0=0;
2260   }
2261   else
2262     intg0=ROUND_UP(dintg);
2263   if (mod)
2264   {
2265     /* we're calculating N1 % N2.
2266        The result will have
2267          frac=MY_MAX(frac1, frac2), as for subtraction
2268          intg=intg2
2269     */
2270     to->sign=from1->sign;
2271     to->frac=MY_MAX(from1->frac, from2->frac);
2272     frac0=0;
2273   }
2274   else
2275   {
2276     /*
2277       we're calculating N1/N2. N1 is in the buf1, has prec1 digits
2278       N2 is in the buf2, has prec2 digits. Scales are frac1 and
2279       frac2 accordingly.
2280       Thus, the result will have
2281          frac = ROUND_UP(frac1+frac2+scale_incr)
2282       and
2283          intg = (prec1-frac1) - (prec2-frac2) + 1
2284          prec = intg+frac
2285     */
2286     frac0=ROUND_UP(frac1+frac2+scale_incr);
2287     FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
2288     to->sign=from1->sign != from2->sign;
2289     to->intg=intg0*DIG_PER_DEC1;
2290     to->frac=frac0*DIG_PER_DEC1;
2291   }
2292   buf0=to->buf;
2293   stop0=buf0+intg0+frac0;
2294   if (likely(div_mod))
2295     while (dintg++ < 0 && buf0 < &to->buf[to->len])
2296     {
2297       *buf0++=0;
2298     }
2299 
2300   len1=(i=ROUND_UP(prec1))+ROUND_UP(2*frac2+scale_incr+1) + 1;
2301   set_if_bigger(len1, 3);
2302   if (!(tmp1=(dec1 *)my_alloca(len1*sizeof(dec1))))
2303     return E_DEC_OOM;
2304   memcpy(tmp1, buf1, i*sizeof(dec1));
2305   bzero(tmp1+i, (len1-i)*sizeof(dec1));
2306 
2307   start1=tmp1;
2308   stop1=start1+len1;
2309   start2=buf2;
2310   stop2=buf2+ROUND_UP(prec2)-1;
2311 
2312   /* removing end zeroes */
2313   while (*stop2 == 0 && stop2 >= start2)
2314     stop2--;
2315   len2= (int) (stop2++ - start2);
2316 
2317   /*
2318     calculating norm2 (normalized *start2) - we need *start2 to be large
2319     (at least > DIG_BASE/2), but unlike Knuth's Alg. D we don't want to
2320     normalize input numbers (as we don't make a copy of the divisor).
2321     Thus we normalize first dec1 of buf2 only, and we'll normalize *start1
2322     on the fly for the purpose of guesstimation only.
2323     It's also faster, as we're saving on normalization of buf2
2324   */
2325   norm_factor=DIG_BASE/(*start2+1);
2326   norm2=(dec1)(norm_factor*start2[0]);
2327   if (unlikely(len2>0))
2328     norm2+=(dec1)(norm_factor*start2[1]/DIG_BASE);
2329 
2330   if (*start1 < *start2)
2331     dcarry=*start1++;
2332   else
2333     dcarry=0;
2334 
2335   /* main loop */
2336   for (; buf0 < stop0; buf0++)
2337   {
2338     /* short-circuit, if possible */
2339     if (unlikely(dcarry == 0 && *start1 < *start2))
2340       guess=0;
2341     else
2342     {
2343       /* D3: make a guess */
2344       x=start1[0]+((dec2)dcarry)*DIG_BASE;
2345       y=start1[1];
2346       guess=(norm_factor*x+norm_factor*y/DIG_BASE)/norm2;
2347       if (unlikely(guess >= DIG_BASE))
2348         guess=DIG_BASE-1;
2349       if (unlikely(len2>0))
2350       {
2351         /* hmm, this is a suspicious trick - I removed normalization here */
2352         if (start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y)
2353           guess--;
2354         if (unlikely(start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y))
2355           guess--;
2356         DBUG_ASSERT(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y);
2357       }
2358 
2359       /* D4: multiply and subtract */
2360       buf2=stop2;
2361       buf1=start1+len2;
2362       DBUG_ASSERT(buf1 < stop1);
2363       for (carry=0; buf2 > start2; buf1--)
2364       {
2365         dec1 hi, lo;
2366         x=guess * (*--buf2);
2367         hi=(dec1)(x/DIG_BASE);
2368         lo=(dec1)(x-((dec2)hi)*DIG_BASE);
2369         SUB2(*buf1, *buf1, lo, carry);
2370         carry+=hi;
2371       }
2372       carry= dcarry < carry;
2373 
2374       /* D5: check the remainder */
2375       if (unlikely(carry))
2376       {
2377         /* D6: correct the guess */
2378         guess--;
2379         buf2=stop2;
2380         buf1=start1+len2;
2381         for (carry=0; buf2 > start2; buf1--)
2382         {
2383           ADD(*buf1, *buf1, *--buf2, carry);
2384         }
2385       }
2386     }
2387     if (likely(div_mod))
2388     {
2389       DBUG_ASSERT(buf0 < to->buf + to->len);
2390       *buf0=(dec1)guess;
2391     }
2392 #ifdef WORKAROUND_GCC_4_3_2_BUG
2393     dcarry= *(volatile dec1 *)start1;
2394 #else
2395     dcarry= *start1;
2396 #endif
2397     start1++;
2398   }
2399   if (mod)
2400   {
2401     /*
2402       now the result is in tmp1, it has
2403         intg=prec1-frac1
2404         frac=MY_MAX(frac1, frac2)=to->frac
2405     */
2406     if (dcarry)
2407       *--start1=dcarry;
2408     buf0=to->buf;
2409     intg0=(int) (ROUND_UP(prec1-frac1)-(start1-tmp1));
2410     frac0=ROUND_UP(to->frac);
2411     error=E_DEC_OK;
2412     if (unlikely(frac0==0 && intg0==0))
2413     {
2414       decimal_make_zero(to);
2415       goto done;
2416     }
2417     if (intg0<=0)
2418     {
2419       if (unlikely(-intg0 >= to->len))
2420       {
2421         decimal_make_zero(to);
2422         error=E_DEC_TRUNCATED;
2423         goto done;
2424       }
2425       stop1= start1 + frac0 + intg0;
2426       frac0+=intg0;
2427       to->intg=0;
2428       while (intg0++ < 0)
2429         *buf0++=0;
2430     }
2431     else
2432     {
2433       if (unlikely(intg0 > to->len))
2434       {
2435         frac0=0;
2436         intg0=to->len;
2437         error=E_DEC_OVERFLOW;
2438         goto done;
2439       }
2440       DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
2441       stop1=start1+frac0+intg0;
2442       to->intg=MY_MIN(intg0*DIG_PER_DEC1, from2->intg);
2443     }
2444     if (unlikely(intg0+frac0 > to->len))
2445     {
2446       stop1-=frac0+intg0-to->len;
2447       frac0=to->len-intg0;
2448       to->frac=frac0*DIG_PER_DEC1;
2449         error=E_DEC_TRUNCATED;
2450     }
2451     DBUG_ASSERT(buf0 + (stop1 - start1) <= to->buf + to->len);
2452     while (start1 < stop1)
2453         *buf0++=*start1++;
2454   }
2455 done:
2456   my_afree(tmp1);
2457   return error;
2458 }
2459 
2460 /*
2461   division of two decimals
2462 
2463   SYNOPSIS
2464     decimal_div()
2465       from1   - dividend
2466       from2   - divisor
2467       to      - quotient
2468 
2469   RETURN VALUE
2470     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2471 
2472   NOTES
2473     see do_div_mod()
2474 */
2475 
2476 int
decimal_div(const decimal_t * from1,const decimal_t * from2,decimal_t * to,int scale_incr)2477 decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to,
2478             int scale_incr)
2479 {
2480   return do_div_mod(from1, from2, to, 0, scale_incr);
2481 }
2482 
2483 /*
2484   modulus
2485 
2486   SYNOPSIS
2487     decimal_mod()
2488       from1   - dividend
2489       from2   - divisor
2490       to      - modulus
2491 
2492   RETURN VALUE
2493     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2494 
2495   NOTES
2496     see do_div_mod()
2497 
2498   DESCRIPTION
2499     the modulus R in    R = M mod N
2500 
2501    is defined as
2502 
2503      0 <= |R| < |M|
2504      sign R == sign M
2505      R = M - k*N, where k is integer
2506 
2507    thus, there's no requirement for M or N to be integers
2508 */
2509 
decimal_mod(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2510 int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2511 {
2512   return do_div_mod(from1, from2, 0, to, 0);
2513 }
2514 
2515 #ifdef MAIN
2516 
2517 int full= 0;
2518 decimal_t a, b, c;
2519 char buf1[100], buf2[100], buf3[100];
2520 
dump_decimal(decimal_t * d)2521 void dump_decimal(decimal_t *d)
2522 {
2523   int i;
2524   printf("/* intg=%d, frac=%d, sign=%d, buf[]={", d->intg, d->frac, d->sign);
2525   for (i=0; i < ROUND_UP(d->frac)+ROUND_UP(d->intg)-1; i++)
2526     printf("%09d, ", d->buf[i]);
2527   printf("%09d} */ ", d->buf[i]);
2528 }
2529 
2530 
check_result_code(int actual,int want)2531 void check_result_code(int actual, int want)
2532 {
2533   if (actual != want)
2534   {
2535     printf("\n^^^^^^^^^^^^^ must return %d\n", want);
2536     exit(1);
2537   }
2538 }
2539 
2540 
print_decimal(decimal_t * d,const char * orig,int actual,int want)2541 void print_decimal(decimal_t *d, const char *orig, int actual, int want)
2542 {
2543   char s[100];
2544   int slen=sizeof(s);
2545 
2546   if (full) dump_decimal(d);
2547   decimal2string(d, s, &slen, 0, 0, 0);
2548   printf("'%s'", s);
2549   check_result_code(actual, want);
2550   if (orig && strcmp(orig, s))
2551   {
2552     printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2553     exit(1);
2554   }
2555 }
2556 
test_d2s()2557 void test_d2s()
2558 {
2559   char s[100];
2560   int slen, res;
2561 
2562   /***********************************/
2563   printf("==== decimal2string ====\n");
2564   a.buf[0]=12345; a.intg=5; a.frac=0; a.sign=0;
2565   slen=sizeof(s);
2566   res=decimal2string(&a, s, &slen, 0, 0, 0);
2567   dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
2568 
2569   a.buf[1]=987000000; a.frac=3;
2570   slen=sizeof(s);
2571   res=decimal2string(&a, s, &slen, 0, 0, 0);
2572   dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
2573 
2574   a.sign=1;
2575   slen=sizeof(s);
2576   res=decimal2string(&a, s, &slen, 0, 0, 0);
2577   dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
2578 
2579   slen=8;
2580   res=decimal2string(&a, s, &slen, 0, 0, 0);
2581   dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
2582 
2583   slen=5;
2584   res=decimal2string(&a, s, &slen, 0, 0, 0);
2585   dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
2586 
2587   a.buf[0]=987000000; a.frac=3; a.intg=0;
2588   slen=sizeof(s);
2589   res=decimal2string(&a, s, &slen, 0, 0, 0);
2590   dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
2591 }
2592 
test_s2d(const char * s,const char * orig,int ex)2593 void test_s2d(const char *s, const char *orig, int ex)
2594 {
2595   char s1[100], *end;
2596   int res;
2597   sprintf(s1, "'%s'", s);
2598   end= strend(s);
2599   printf("len=%2d %-30s => res=%d    ", a.len, s1,
2600          (res= string2decimal(s, &a, &end)));
2601   print_decimal(&a, orig, res, ex);
2602   printf("\n");
2603 }
2604 
test_d2f(const char * s,int ex)2605 void test_d2f(const char *s, int ex)
2606 {
2607   char s1[100], *end;
2608   double x;
2609   int res;
2610 
2611   sprintf(s1, "'%s'", s);
2612   end= strend(s);
2613   string2decimal(s, &a, &end);
2614   res=decimal2double(&a, &x);
2615   if (full) dump_decimal(&a);
2616   printf("%-40s => res=%d    %.*g\n", s1, res, a.intg+a.frac, x);
2617   check_result_code(res, ex);
2618 }
2619 
test_d2b2d(const char * str,int p,int s,const char * orig,int ex)2620 void test_d2b2d(const char *str, int p, int s, const char *orig, int ex)
2621 {
2622   char s1[100], buf[100], *end;
2623   int res, i, size=decimal_bin_size(p, s);
2624 
2625   sprintf(s1, "'%s'", str);
2626   end= strend(str);
2627   string2decimal(str, &a, &end);
2628   res=decimal2bin(&a, buf, p, s);
2629   printf("%-31s {%2d, %2d} => res=%d size=%-2d ", s1, p, s, res, size);
2630   if (full)
2631   {
2632     printf("0x");
2633     for (i=0; i < size; i++)
2634       printf("%02x", ((uchar *)buf)[i]);
2635   }
2636   res=bin2decimal(buf, &a, p, s);
2637   printf(" => res=%d ", res);
2638   print_decimal(&a, orig, res, ex);
2639   printf("\n");
2640 }
2641 
test_f2d(double from,int ex)2642 void test_f2d(double from, int ex)
2643 {
2644   int res;
2645 
2646   res=double2decimal(from, &a);
2647   printf("%-40.*f => res=%d    ", DBL_DIG-2, from, res);
2648   print_decimal(&a, 0, res, ex);
2649   printf("\n");
2650 }
2651 
test_ull2d(ulonglong from,const char * orig,int ex)2652 void test_ull2d(ulonglong from, const char *orig, int ex)
2653 {
2654   char s[100];
2655   int res;
2656 
2657   res=ulonglong2decimal(from, &a);
2658   longlong10_to_str(from,s,10);
2659   printf("%-40s => res=%d    ", s, res);
2660   print_decimal(&a, orig, res, ex);
2661   printf("\n");
2662 }
2663 
test_ll2d(longlong from,const char * orig,int ex)2664 void test_ll2d(longlong from, const char *orig, int ex)
2665 {
2666   char s[100];
2667   int res;
2668 
2669   res=longlong2decimal(from, &a);
2670   longlong10_to_str(from,s,-10);
2671   printf("%-40s => res=%d    ", s, res);
2672   print_decimal(&a, orig, res, ex);
2673   printf("\n");
2674 }
2675 
test_d2ull(const char * s,const char * orig,int ex)2676 void test_d2ull(const char *s, const char *orig, int ex)
2677 {
2678   char s1[100], *end;
2679   ulonglong x;
2680   int res;
2681 
2682   end= strend(s);
2683   string2decimal(s, &a, &end);
2684   res=decimal2ulonglong(&a, &x);
2685   if (full) dump_decimal(&a);
2686   longlong10_to_str(x,s1,10);
2687   printf("%-40s => res=%d    %s\n", s, res, s1);
2688   check_result_code(res, ex);
2689   if (orig && strcmp(orig, s1))
2690   {
2691     printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2692     exit(1);
2693   }
2694 }
2695 
test_d2ll(const char * s,const char * orig,int ex)2696 void test_d2ll(const char *s, const char *orig, int ex)
2697 {
2698   char s1[100], *end;
2699   longlong x;
2700   int res;
2701 
2702   end= strend(s);
2703   string2decimal(s, &a, &end);
2704   res=decimal2longlong(&a, &x);
2705   if (full) dump_decimal(&a);
2706   longlong10_to_str(x,s1,-10);
2707   printf("%-40s => res=%d    %s\n", s, res, s1);
2708   check_result_code(res, ex);
2709   if (orig && strcmp(orig, s1))
2710   {
2711     printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2712     exit(1);
2713   }
2714 }
2715 
test_da(const char * s1,const char * s2,const char * orig,int ex)2716 void test_da(const char *s1, const char *s2, const char *orig, int ex)
2717 {
2718   char s[100], *end;
2719   int res;
2720   sprintf(s, "'%s' + '%s'", s1, s2);
2721   end= strend(s1);
2722   string2decimal(s1, &a, &end);
2723   end= strend(s2);
2724   string2decimal(s2, &b, &end);
2725   res=decimal_add(&a, &b, &c);
2726   printf("%-40s => res=%d    ", s, res);
2727   print_decimal(&c, orig, res, ex);
2728   printf("\n");
2729 }
2730 
test_ds(const char * s1,const char * s2,const char * orig,int ex)2731 void test_ds(const char *s1, const char *s2, const char *orig, int ex)
2732 {
2733   char s[100], *end;
2734   int res;
2735   sprintf(s, "'%s' - '%s'", s1, s2);
2736   end= strend(s1);
2737   string2decimal(s1, &a, &end);
2738   end= strend(s2);
2739   string2decimal(s2, &b, &end);
2740   res=decimal_sub(&a, &b, &c);
2741   printf("%-40s => res=%d    ", s, res);
2742   print_decimal(&c, orig, res, ex);
2743   printf("\n");
2744 }
2745 
test_dc(const char * s1,const char * s2,int orig)2746 void test_dc(const char *s1, const char *s2, int orig)
2747 {
2748   char s[100], *end;
2749   int res;
2750   sprintf(s, "'%s' <=> '%s'", s1, s2);
2751   end= strend(s1);
2752   string2decimal(s1, &a, &end);
2753   end= strend(s2);
2754   string2decimal(s2, &b, &end);
2755   res=decimal_cmp(&a, &b);
2756   printf("%-40s => res=%d\n", s, res);
2757   if (orig != res)
2758   {
2759     printf("\n^^^^^^^^^^^^^ must've been %d\n", orig);
2760     exit(1);
2761   }
2762 }
2763 
test_dm(const char * s1,const char * s2,const char * orig,int ex)2764 void test_dm(const char *s1, const char *s2, const char *orig, int ex)
2765 {
2766   char s[100], *end;
2767   int res;
2768   sprintf(s, "'%s' * '%s'", s1, s2);
2769   end= strend(s1);
2770   string2decimal(s1, &a, &end);
2771   end= strend(s2);
2772   string2decimal(s2, &b, &end);
2773   res=decimal_mul(&a, &b, &c);
2774   printf("%-40s => res=%d    ", s, res);
2775   print_decimal(&c, orig, res, ex);
2776   printf("\n");
2777 }
2778 
test_dv(const char * s1,const char * s2,const char * orig,int ex)2779 void test_dv(const char *s1, const char *s2, const char *orig, int ex)
2780 {
2781   char s[100], *end;
2782   int res;
2783   sprintf(s, "'%s' / '%s'", s1, s2);
2784   end= strend(s1);
2785   string2decimal(s1, &a, &end);
2786   end= strend(s2);
2787   string2decimal(s2, &b, &end);
2788   res=decimal_div(&a, &b, &c, 5);
2789   printf("%-40s => res=%d    ", s, res);
2790   check_result_code(res, ex);
2791   if (res == E_DEC_DIV_ZERO)
2792     printf("E_DEC_DIV_ZERO");
2793   else
2794     print_decimal(&c, orig, res, ex);
2795   printf("\n");
2796 }
2797 
test_md(const char * s1,const char * s2,const char * orig,int ex)2798 void test_md(const char *s1, const char *s2, const char *orig, int ex)
2799 {
2800   char s[100], *end;
2801   int res;
2802   sprintf(s, "'%s' %% '%s'", s1, s2);
2803   end= strend(s1);
2804   string2decimal(s1, &a, &end);
2805   end= strend(s2);
2806   string2decimal(s2, &b, &end);
2807   res=decimal_mod(&a, &b, &c);
2808   printf("%-40s => res=%d    ", s, res);
2809   check_result_code(res, ex);
2810   if (res == E_DEC_DIV_ZERO)
2811     printf("E_DEC_DIV_ZERO");
2812   else
2813     print_decimal(&c, orig, res, ex);
2814   printf("\n");
2815 }
2816 
2817 const char *round_mode[]=
2818 {"TRUNCATE", "HALF_EVEN", "HALF_UP", "CEILING", "FLOOR"};
2819 
test_ro(const char * s1,int n,decimal_round_mode mode,const char * orig,int ex)2820 void test_ro(const char *s1, int n, decimal_round_mode mode, const char *orig,
2821              int ex)
2822 {
2823   char s[100], *end;
2824   int res;
2825   sprintf(s, "'%s', %d, %s", s1, n, round_mode[mode]);
2826   end= strend(s1);
2827   string2decimal(s1, &a, &end);
2828   res=decimal_round(&a, &b, n, mode);
2829   printf("%-40s => res=%d    ", s, res);
2830   print_decimal(&b, orig, res, ex);
2831   printf("\n");
2832 }
2833 
2834 
test_mx(int precision,int frac,const char * orig)2835 void test_mx(int precision, int frac, const char *orig)
2836 {
2837   char s[100];
2838   sprintf(s, "%d, %d", precision, frac);
2839   max_decimal(precision, frac, &a);
2840   printf("%-40s =>          ", s);
2841   print_decimal(&a, orig, 0, 0);
2842   printf("\n");
2843 }
2844 
2845 
test_pr(const char * s1,int prec,int dec,char filler,const char * orig,int ex)2846 void test_pr(const char *s1, int prec, int dec, char filler, const char *orig,
2847              int ex)
2848 {
2849   char s[100], *end;
2850   char s2[100];
2851   int slen= sizeof(s2);
2852   int res;
2853 
2854   sprintf(s, filler ? "'%s', %d, %d, '%c'" : "'%s', %d, %d, '\\0'",
2855           s1, prec, dec, filler);
2856   end= strend(s1);
2857   string2decimal(s1, &a, &end);
2858   res= decimal2string(&a, s2, &slen, prec, dec, filler);
2859   printf("%-40s => res=%d    '%s'", s, res, s2);
2860   check_result_code(res, ex);
2861   if (orig && strcmp(orig, s2))
2862   {
2863     printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2864     exit(1);
2865   }
2866   printf("\n");
2867 }
2868 
2869 
test_sh(const char * s1,int shift,const char * orig,int ex)2870 void test_sh(const char *s1, int shift, const char *orig, int ex)
2871 {
2872   char s[100], *end;
2873   int res;
2874   sprintf(s, "'%s' %s %d", s1, ((shift < 0) ? ">>" : "<<"), abs(shift));
2875   end= strend(s1);
2876   string2decimal(s1, &a, &end);
2877   res= decimal_shift(&a, shift);
2878   printf("%-40s => res=%d    ", s, res);
2879   print_decimal(&a, orig, res, ex);
2880   printf("\n");
2881 }
2882 
2883 
test_fr(const char * s1,const char * orig)2884 void test_fr(const char *s1, const char *orig)
2885 {
2886   char s[100], *end;
2887   sprintf(s, "'%s'", s1);
2888   printf("%-40s =>          ", s);
2889   end= strend(s1);
2890   string2decimal(s1, &a, &end);
2891   a.frac= decimal_actual_fraction(&a);
2892   print_decimal(&a, orig, 0, 0);
2893   printf("\n");
2894 }
2895 
2896 
main()2897 int main()
2898 {
2899   a.buf=(void*)buf1;
2900   a.len=sizeof(buf1)/sizeof(dec1);
2901   b.buf=(void*)buf2;
2902   b.len=sizeof(buf2)/sizeof(dec1);
2903   c.buf=(void*)buf3;
2904   c.len=sizeof(buf3)/sizeof(dec1);
2905 
2906   if (full)
2907     test_d2s();
2908 
2909   printf("==== string2decimal ====\n");
2910   test_s2d("12345", "12345", 0);
2911   test_s2d("12345.", "12345", 0);
2912   test_s2d("123.45", "123.45", 0);
2913   test_s2d("-123.45", "-123.45", 0);
2914   test_s2d(".00012345000098765", "0.00012345000098765", 0);
2915   test_s2d(".12345000098765", "0.12345000098765", 0);
2916   test_s2d("-.000000012345000098765", "-0.000000012345000098765", 0);
2917   test_s2d("1234500009876.5", "1234500009876.5", 0);
2918   a.len=1;
2919   test_s2d("123450000098765", "98765", 2);
2920   test_s2d("123450.000098765", "123450", 1);
2921   a.len=sizeof(buf1)/sizeof(dec1);
2922   test_s2d("123E5", "12300000", 0);
2923   test_s2d("123E-2", "1.23", 0);
2924 
2925   printf("==== decimal2double ====\n");
2926   test_d2f("12345", 0);
2927   test_d2f("123.45", 0);
2928   test_d2f("-123.45", 0);
2929   test_d2f("0.00012345000098765", 0);
2930   test_d2f("1234500009876.5", 0);
2931 
2932   printf("==== double2decimal ====\n");
2933   test_f2d(12345, 0);
2934   test_f2d(1.0/3, 0);
2935   test_f2d(-123.45, 0);
2936   test_f2d(0.00012345000098765, 0);
2937   test_f2d(1234500009876.5, 0);
2938 
2939   printf("==== ulonglong2decimal ====\n");
2940   test_ull2d(ULL(12345), "12345", 0);
2941   test_ull2d(ULL(0), "0", 0);
2942   test_ull2d(ULL(18446744073709551615), "18446744073709551615", 0);
2943 
2944   printf("==== decimal2ulonglong ====\n");
2945   test_d2ull("12345", "12345", 0);
2946   test_d2ull("0", "0", 0);
2947   test_d2ull("18446744073709551615", "18446744073709551615", 0);
2948   test_d2ull("18446744073709551616", "18446744073", 2);
2949   test_d2ull("-1", "0", 2);
2950   test_d2ull("1.23", "1", 1);
2951   test_d2ull("9999999999999999999999999.000", "9999999999999999", 2);
2952 
2953   printf("==== longlong2decimal ====\n");
2954   test_ll2d(LL(-12345), "-12345", 0);
2955   test_ll2d(LL(-1), "-1", 0);
2956   test_ll2d(LL(-9223372036854775807), "-9223372036854775807", 0);
2957   test_ll2d(ULL(9223372036854775808), "-9223372036854775808", 0);
2958 
2959   printf("==== decimal2longlong ====\n");
2960   test_d2ll("18446744073709551615", "18446744073", 2);
2961   test_d2ll("-1", "-1", 0);
2962   test_d2ll("-1.23", "-1", 1);
2963   test_d2ll("-9223372036854775807", "-9223372036854775807", 0);
2964   test_d2ll("-9223372036854775808", "-9223372036854775808", 0);
2965   test_d2ll("9223372036854775808", "9223372036854775807", 2);
2966 
2967   printf("==== do_add ====\n");
2968   test_da(".00012345000098765" ,"123.45", "123.45012345000098765", 0);
2969   test_da(".1" ,".45", "0.55", 0);
2970   test_da("1234500009876.5" ,".00012345000098765", "1234500009876.50012345000098765", 0);
2971   test_da("9999909999999.5" ,".555", "9999910000000.055", 0);
2972   test_da("99999999" ,"1", "100000000", 0);
2973   test_da("989999999" ,"1", "990000000", 0);
2974   test_da("999999999" ,"1", "1000000000", 0);
2975   test_da("12345" ,"123.45", "12468.45", 0);
2976   test_da("-12345" ,"-123.45", "-12468.45", 0);
2977   test_ds("-12345" ,"123.45", "-12468.45", 0);
2978   test_ds("12345" ,"-123.45", "12468.45", 0);
2979 
2980   printf("==== do_sub ====\n");
2981   test_ds(".00012345000098765", "123.45","-123.44987654999901235", 0);
2982   test_ds("1234500009876.5", ".00012345000098765","1234500009876.49987654999901235", 0);
2983   test_ds("9999900000000.5", ".555","9999899999999.945", 0);
2984   test_ds("1111.5551", "1111.555","0.0001", 0);
2985   test_ds(".555", ".555","0", 0);
2986   test_ds("10000000", "1","9999999", 0);
2987   test_ds("1000001000", ".1","1000000999.9", 0);
2988   test_ds("1000000000", ".1","999999999.9", 0);
2989   test_ds("12345", "123.45","12221.55", 0);
2990   test_ds("-12345", "-123.45","-12221.55", 0);
2991   test_da("-12345", "123.45","-12221.55", 0);
2992   test_da("12345", "-123.45","12221.55", 0);
2993   test_ds("123.45", "12345","-12221.55", 0);
2994   test_ds("-123.45", "-12345","12221.55", 0);
2995   test_da("123.45", "-12345","-12221.55", 0);
2996   test_da("-123.45", "12345","12221.55", 0);
2997   test_da("5", "-6.0","-1.0", 0);
2998 
2999   printf("==== decimal_mul ====\n");
3000   test_dm("12", "10","120", 0);
3001   test_dm("-123.456", "98765.4321","-12193185.1853376", 0);
3002   test_dm("-123456000000", "98765432100000","-12193185185337600000000000", 0);
3003   test_dm("123456", "987654321","121931851853376", 0);
3004   test_dm("123456", "9876543210","1219318518533760", 0);
3005   test_dm("123", "0.01","1.23", 0);
3006   test_dm("123", "0","0", 0);
3007 
3008   printf("==== decimal_div ====\n");
3009   test_dv("120", "10","12.000000000", 0);
3010   test_dv("123", "0.01","12300.000000000", 0);
3011   test_dv("120", "100000000000.00000","0.000000001200000000", 0);
3012   test_dv("123", "0","", 4);
3013   test_dv("0", "0", "", 4);
3014   test_dv("-12193185.1853376", "98765.4321","-123.456000000000000000", 0);
3015   test_dv("121931851853376", "987654321","123456.000000000", 0);
3016   test_dv("0", "987","0", 0);
3017   test_dv("1", "3","0.333333333", 0);
3018   test_dv("1.000000000000", "3","0.333333333333333333", 0);
3019   test_dv("1", "1","1.000000000", 0);
3020   test_dv("0.0123456789012345678912345", "9999999999","0.000000000001234567890246913578148141", 0);
3021   test_dv("10.333000000", "12.34500","0.837019036046982584042122316", 0);
3022   test_dv("10.000000000060", "2","5.000000000030000000", 0);
3023 
3024   printf("==== decimal_mod ====\n");
3025   test_md("234","10","4", 0);
3026   test_md("234.567","10.555","2.357", 0);
3027   test_md("-234.567","10.555","-2.357", 0);
3028   test_md("234.567","-10.555","2.357", 0);
3029   c.buf[1]=0x3ABECA;
3030   test_md("99999999999999999999999999999999999999","3","0", 0);
3031   if (c.buf[1] != 0x3ABECA)
3032   {
3033     printf("%X - overflow\n", c.buf[1]);
3034     exit(1);
3035   }
3036 
3037   printf("==== decimal2bin/bin2decimal ====\n");
3038   test_d2b2d("-10.55", 4, 2,"-10.55", 0);
3039   test_d2b2d("0.0123456789012345678912345", 30, 25,"0.0123456789012345678912345", 0);
3040   test_d2b2d("12345", 5, 0,"12345", 0);
3041   test_d2b2d("12345", 10, 3,"12345.000", 0);
3042   test_d2b2d("123.45", 10, 3,"123.450", 0);
3043   test_d2b2d("-123.45", 20, 10,"-123.4500000000", 0);
3044   test_d2b2d(".00012345000098765", 15, 14,"0.00012345000098", 0);
3045   test_d2b2d(".00012345000098765", 22, 20,"0.00012345000098765000", 0);
3046   test_d2b2d(".12345000098765", 30, 20,"0.12345000098765000000", 0);
3047   test_d2b2d("-.000000012345000098765", 30, 20,"-0.00000001234500009876", 0);
3048   test_d2b2d("1234500009876.5", 30, 5,"1234500009876.50000", 0);
3049   test_d2b2d("111111111.11", 10, 2,"11111111.11", 0);
3050   test_d2b2d("000000000.01", 7, 3,"0.010", 0);
3051   test_d2b2d("123.4", 10, 2, "123.40", 0);
3052 
3053 
3054   printf("==== decimal_cmp ====\n");
3055   test_dc("12","13",-1);
3056   test_dc("13","12",1);
3057   test_dc("-10","10",-1);
3058   test_dc("10","-10",1);
3059   test_dc("-12","-13",1);
3060   test_dc("0","12",-1);
3061   test_dc("-10","0",-1);
3062   test_dc("4","4",0);
3063 
3064   printf("==== decimal_round ====\n");
3065   test_ro("5678.123451",-4,TRUNCATE,"0", 0);
3066   test_ro("5678.123451",-3,TRUNCATE,"5000", 0);
3067   test_ro("5678.123451",-2,TRUNCATE,"5600", 0);
3068   test_ro("5678.123451",-1,TRUNCATE,"5670", 0);
3069   test_ro("5678.123451",0,TRUNCATE,"5678", 0);
3070   test_ro("5678.123451",1,TRUNCATE,"5678.1", 0);
3071   test_ro("5678.123451",2,TRUNCATE,"5678.12", 0);
3072   test_ro("5678.123451",3,TRUNCATE,"5678.123", 0);
3073   test_ro("5678.123451",4,TRUNCATE,"5678.1234", 0);
3074   test_ro("5678.123451",5,TRUNCATE,"5678.12345", 0);
3075   test_ro("5678.123451",6,TRUNCATE,"5678.123451", 0);
3076   test_ro("-5678.123451",-4,TRUNCATE,"0", 0);
3077   memset(buf2, 33, sizeof(buf2));
3078   test_ro("99999999999999999999999999999999999999",-31,TRUNCATE,"99999990000000000000000000000000000000", 0);
3079   test_ro("15.1",0,HALF_UP,"15", 0);
3080   test_ro("15.5",0,HALF_UP,"16", 0);
3081   test_ro("15.9",0,HALF_UP,"16", 0);
3082   test_ro("-15.1",0,HALF_UP,"-15", 0);
3083   test_ro("-15.5",0,HALF_UP,"-16", 0);
3084   test_ro("-15.9",0,HALF_UP,"-16", 0);
3085   test_ro("15.1",1,HALF_UP,"15.1", 0);
3086   test_ro("-15.1",1,HALF_UP,"-15.1", 0);
3087   test_ro("15.17",1,HALF_UP,"15.2", 0);
3088   test_ro("15.4",-1,HALF_UP,"20", 0);
3089   test_ro("-15.4",-1,HALF_UP,"-20", 0);
3090   test_ro("5.4",-1,HALF_UP,"10", 0);
3091   test_ro(".999", 0, HALF_UP, "1", 0);
3092   memset(buf2, 33, sizeof(buf2));
3093   test_ro("999999999", -9, HALF_UP, "1000000000", 0);
3094   test_ro("15.1",0,HALF_EVEN,"15", 0);
3095   test_ro("15.5",0,HALF_EVEN,"16", 0);
3096   test_ro("14.5",0,HALF_EVEN,"14", 0);
3097   test_ro("15.9",0,HALF_EVEN,"16", 0);
3098   test_ro("15.1",0,CEILING,"16", 0);
3099   test_ro("-15.1",0,CEILING,"-15", 0);
3100   test_ro("15.1",0,FLOOR,"15", 0);
3101   test_ro("-15.1",0,FLOOR,"-16", 0);
3102   test_ro("999999999999999999999.999", 0, CEILING,"1000000000000000000000", 0);
3103   test_ro("-999999999999999999999.999", 0, FLOOR,"-1000000000000000000000", 0);
3104 
3105   b.buf[0]=DIG_BASE+1;
3106   b.buf++;
3107   test_ro(".3", 0, HALF_UP, "0", 0);
3108   b.buf--;
3109   if (b.buf[0] != DIG_BASE+1)
3110   {
3111     printf("%d - underflow\n", b.buf[0]);
3112     exit(1);
3113   }
3114 
3115   printf("==== max_decimal ====\n");
3116   test_mx(1,1,"0.9");
3117   test_mx(1,0,"9");
3118   test_mx(2,1,"9.9");
3119   test_mx(4,2,"99.99");
3120   test_mx(6,3,"999.999");
3121   test_mx(8,4,"9999.9999");
3122   test_mx(10,5,"99999.99999");
3123   test_mx(12,6,"999999.999999");
3124   test_mx(14,7,"9999999.9999999");
3125   test_mx(16,8,"99999999.99999999");
3126   test_mx(18,9,"999999999.999999999");
3127   test_mx(20,10,"9999999999.9999999999");
3128   test_mx(20,20,"0.99999999999999999999");
3129   test_mx(20,0,"99999999999999999999");
3130   test_mx(40,20,"99999999999999999999.99999999999999999999");
3131 
3132   printf("==== decimal2string ====\n");
3133   test_pr("123.123", 0, 0, 0, "123.123", 0);
3134   test_pr("123.123", 7, 3, '0', "123.123", 0);
3135   test_pr("123.123", 9, 3, '0', "00123.123", 0);
3136   test_pr("123.123", 9, 4, '0', "0123.1230", 0);
3137   test_pr("123.123", 9, 5, '0', "123.12300", 0);
3138   test_pr("123.123", 9, 2, '0', "000123.12", 1);
3139   test_pr("123.123", 9, 6, '0', "23.123000", 2);
3140 
3141   printf("==== decimal_shift ====\n");
3142   test_sh("123.123", 1, "1231.23", 0);
3143   test_sh("123457189.123123456789000", 1, "1234571891.23123456789", 0);
3144   test_sh("123457189.123123456789000", 4, "1234571891231.23456789", 0);
3145   test_sh("123457189.123123456789000", 8, "12345718912312345.6789", 0);
3146   test_sh("123457189.123123456789000", 9, "123457189123123456.789", 0);
3147   test_sh("123457189.123123456789000", 10, "1234571891231234567.89", 0);
3148   test_sh("123457189.123123456789000", 17, "12345718912312345678900000", 0);
3149   test_sh("123457189.123123456789000", 18, "123457189123123456789000000", 0);
3150   test_sh("123457189.123123456789000", 19, "1234571891231234567890000000", 0);
3151   test_sh("123457189.123123456789000", 26, "12345718912312345678900000000000000", 0);
3152   test_sh("123457189.123123456789000", 27, "123457189123123456789000000000000000", 0);
3153   test_sh("123457189.123123456789000", 28, "1234571891231234567890000000000000000", 0);
3154   test_sh("000000000000000000000000123457189.123123456789000", 26, "12345718912312345678900000000000000", 0);
3155   test_sh("00000000123457189.123123456789000", 27, "123457189123123456789000000000000000", 0);
3156   test_sh("00000000000000000123457189.123123456789000", 28, "1234571891231234567890000000000000000", 0);
3157   test_sh("123", 1, "1230", 0);
3158   test_sh("123", 10, "1230000000000", 0);
3159   test_sh(".123", 1, "1.23", 0);
3160   test_sh(".123", 10, "1230000000", 0);
3161   test_sh(".123", 14, "12300000000000", 0);
3162   test_sh("000.000", 1000, "0", 0);
3163   test_sh("000.", 1000, "0", 0);
3164   test_sh(".000", 1000, "0", 0);
3165   test_sh("1", 1000, "1", 2);
3166   test_sh("123.123", -1, "12.3123", 0);
3167   test_sh("123987654321.123456789000", -1, "12398765432.1123456789", 0);
3168   test_sh("123987654321.123456789000", -2, "1239876543.21123456789", 0);
3169   test_sh("123987654321.123456789000", -3, "123987654.321123456789", 0);
3170   test_sh("123987654321.123456789000", -8, "1239.87654321123456789", 0);
3171   test_sh("123987654321.123456789000", -9, "123.987654321123456789", 0);
3172   test_sh("123987654321.123456789000", -10, "12.3987654321123456789", 0);
3173   test_sh("123987654321.123456789000", -11, "1.23987654321123456789", 0);
3174   test_sh("123987654321.123456789000", -12, "0.123987654321123456789", 0);
3175   test_sh("123987654321.123456789000", -13, "0.0123987654321123456789", 0);
3176   test_sh("123987654321.123456789000", -14, "0.00123987654321123456789", 0);
3177   test_sh("00000087654321.123456789000", -14, "0.00000087654321123456789", 0);
3178   a.len= 2;
3179   test_sh("123.123", -2, "1.23123", 0);
3180   test_sh("123.123", -3, "0.123123", 0);
3181   test_sh("123.123", -6, "0.000123123", 0);
3182   test_sh("123.123", -7, "0.0000123123", 0);
3183   test_sh("123.123", -15, "0.000000000000123123", 0);
3184   test_sh("123.123", -16, "0.000000000000012312", 1);
3185   test_sh("123.123", -17, "0.000000000000001231", 1);
3186   test_sh("123.123", -18, "0.000000000000000123", 1);
3187   test_sh("123.123", -19, "0.000000000000000012", 1);
3188   test_sh("123.123", -20, "0.000000000000000001", 1);
3189   test_sh("123.123", -21, "0", 1);
3190   test_sh(".000000000123", -1, "0.0000000000123", 0);
3191   test_sh(".000000000123", -6, "0.000000000000000123", 0);
3192   test_sh(".000000000123", -7, "0.000000000000000012", 1);
3193   test_sh(".000000000123", -8, "0.000000000000000001", 1);
3194   test_sh(".000000000123", -9, "0", 1);
3195   test_sh(".000000000123", 1, "0.00000000123", 0);
3196   test_sh(".000000000123", 8, "0.0123", 0);
3197   test_sh(".000000000123", 9, "0.123", 0);
3198   test_sh(".000000000123", 10, "1.23", 0);
3199   test_sh(".000000000123", 17, "12300000", 0);
3200   test_sh(".000000000123", 18, "123000000", 0);
3201   test_sh(".000000000123", 19, "1230000000", 0);
3202   test_sh(".000000000123", 20, "12300000000", 0);
3203   test_sh(".000000000123", 21, "123000000000", 0);
3204   test_sh(".000000000123", 22, "1230000000000", 0);
3205   test_sh(".000000000123", 23, "12300000000000", 0);
3206   test_sh(".000000000123", 24, "123000000000000", 0);
3207   test_sh(".000000000123", 25, "1230000000000000", 0);
3208   test_sh(".000000000123", 26, "12300000000000000", 0);
3209   test_sh(".000000000123", 27, "123000000000000000", 0);
3210   test_sh(".000000000123", 28, "0.000000000123", 2);
3211   test_sh("123456789.987654321", -1, "12345678.998765432", 1);
3212   test_sh("123456789.987654321", -2, "1234567.899876543", 1);
3213   test_sh("123456789.987654321", -8, "1.234567900", 1);
3214   test_sh("123456789.987654321", -9, "0.123456789987654321", 0);
3215   test_sh("123456789.987654321", -10, "0.012345678998765432", 1);
3216   test_sh("123456789.987654321", -17, "0.000000001234567900", 1);
3217   test_sh("123456789.987654321", -18, "0.000000000123456790", 1);
3218   test_sh("123456789.987654321", -19, "0.000000000012345679", 1);
3219   test_sh("123456789.987654321", -26, "0.000000000000000001", 1);
3220   test_sh("123456789.987654321", -27, "0", 1);
3221   test_sh("123456789.987654321", 1, "1234567900", 1);
3222   test_sh("123456789.987654321", 2, "12345678999", 1);
3223   test_sh("123456789.987654321", 4, "1234567899877", 1);
3224   test_sh("123456789.987654321", 8, "12345678998765432", 1);
3225   test_sh("123456789.987654321", 9, "123456789987654321", 0);
3226   test_sh("123456789.987654321", 10, "123456789.987654321", 2);
3227   test_sh("123456789.987654321", 0, "123456789.987654321", 0);
3228   a.len= sizeof(buf1)/sizeof(dec1);
3229 
3230   printf("==== decimal_actual_fraction ====\n");
3231   test_fr("1.123456789000000000", "1.123456789");
3232   test_fr("1.12345678000000000", "1.12345678");
3233   test_fr("1.1234567000000000", "1.1234567");
3234   test_fr("1.123456000000000", "1.123456");
3235   test_fr("1.12345000000000", "1.12345");
3236   test_fr("1.1234000000000", "1.1234");
3237   test_fr("1.123000000000", "1.123");
3238   test_fr("1.12000000000", "1.12");
3239   test_fr("1.1000000000", "1.1");
3240   test_fr("1.000000000", "1");
3241   test_fr("1.0", "1");
3242   test_fr("10000000000000000000.0", "10000000000000000000");
3243 
3244   return 0;
3245 }
3246 #endif
3247