1 /* Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    Without limiting anything contained in the foregoing, this file,
15    which is part of C Driver for MySQL (Connector/C), is also subject to the
16    Universal FOSS Exception, version 1.0, a copy of which can be found at
17    http://oss.oracle.com/licenses/universal-foss-exception.
18 
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License, version 2.0, for more details.
23 
24    You should have received a copy of the GNU General Public License
25    along with this program; if not, write to the Free Software
26    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
27 
28 /*
29 =======================================================================
30   NOTE: this library implements SQL standard "exact numeric" type
31   and is not at all generic, but rather intentinally crippled to
32   follow the standard :)
33 =======================================================================
34   Quoting the standard
35   (SQL:2003, Part 2 Foundations, aka ISO/IEC 9075-2:2003)
36 
37 4.4.2 Characteristics of numbers, page 27:
38 
39   An exact numeric type has a precision P and a scale S. P is a positive
40   integer that determines the number of significant digits in a
41   particular radix R, where R is either 2 or 10. S is a non-negative
42   integer. Every value of an exact numeric type of scale S is of the
43   form n*10^{-S}, where n is an integer such that �-R^P <= n <= R^P.
44 
45   [...]
46 
47   If an assignment of some number would result in a loss of its most
48   significant digit, an exception condition is raised. If least
49   significant digits are lost, implementation-defined rounding or
50   truncating occurs, with no exception condition being raised.
51 
52   [...]
53 
54   Whenever an exact or approximate numeric value is assigned to an exact
55   numeric value site, an approximation of its value that preserves
56   leading significant digits after rounding or truncating is represented
57   in the declared type of the target. The value is converted to have the
58   precision and scale of the target. The choice of whether to truncate
59   or round is implementation-defined.
60 
61   [...]
62 
63   All numeric values between the smallest and the largest value,
64   inclusive, in a given exact numeric type have an approximation
65   obtained by rounding or truncation for that type; it is
66   implementation-defined which other numeric values have such
67   approximations.
68 
69 5.3 <literal>, page 143
70 
71   <exact numeric literal> ::=
72     <unsigned integer> [ <period> [ <unsigned integer> ] ]
73   | <period> <unsigned integer>
74 
75 6.1 <data type>, page 165:
76 
77   19) The <scale> of an <exact numeric type> shall not be greater than
78       the <precision> of the <exact numeric type>.
79 
80   20) For the <exact numeric type>s DECIMAL and NUMERIC:
81 
82     a) The maximum value of <precision> is implementation-defined.
83        <precision> shall not be greater than this value.
84     b) The maximum value of <scale> is implementation-defined. <scale>
85        shall not be greater than this maximum value.
86 
87   21) NUMERIC specifies the data type exact numeric, with the decimal
88       precision and scale specified by the <precision> and <scale>.
89 
90   22) DECIMAL specifies the data type exact numeric, with the decimal
91       scale specified by the <scale> and the implementation-defined
92       decimal precision equal to or greater than the value of the
93       specified <precision>.
94 
95 6.26 <numeric value expression>, page 241:
96 
97   1) If the declared type of both operands of a dyadic arithmetic
98      operator is exact numeric, then the declared type of the result is
99      an implementation-defined exact numeric type, with precision and
100      scale determined as follows:
101 
102    a) Let S1 and S2 be the scale of the first and second operands
103       respectively.
104    b) The precision of the result of addition and subtraction is
105       implementation-defined, and the scale is the maximum of S1 and S2.
106    c) The precision of the result of multiplication is
107       implementation-defined, and the scale is S1 + S2.
108    d) The precision and scale of the result of division are
109       implementation-defined.
110 */
111 
112 #include <my_global.h>
113 #include <m_ctype.h>
114 #include <myisampack.h>
115 #include <my_sys.h> /* for my_alloca */
116 #include <m_string.h>
117 #include <decimal.h>
118 
119 /*
120   Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
121   So one variable of type decimal_digit_t is limited:
122 
123       0 < decimal_digit <= DIG_MAX < DIG_BASE
124 
125   in the struct st_decimal_t:
126 
127     intg is the number of *decimal* digits (NOT number of decimal_digit_t's !)
128          before the point
129     frac - number of decimal digits after the point
130     buf is an array of decimal_digit_t's
131     len is the length of buf (length of allocated space) in decimal_digit_t's,
132         not in bytes
133 */
134 typedef decimal_digit_t dec1;
135 typedef longlong      dec2;
136 
137 #define DIG_PER_DEC1 9
138 #define DIG_MASK     100000000
139 #define DIG_BASE     1000000000
140 #define DIG_MAX      (DIG_BASE-1)
141 #define DIG_BASE2    ((dec2)DIG_BASE * (dec2)DIG_BASE)
142 #define ROUND_UP(X)  (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
143 static const dec1 powers10[DIG_PER_DEC1+1]={
144   1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
145 static const int dig2bytes[DIG_PER_DEC1+1]={0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
146 static const dec1 frac_max[DIG_PER_DEC1-1]={
147   900000000, 990000000, 999000000,
148   999900000, 999990000, 999999000,
149   999999900, 999999990 };
150 
151 #define sanity(d) DBUG_ASSERT((d)->len >0)
152 
153 #define FIX_INTG_FRAC_ERROR(len, intg1, frac1, error)                   \
154         do                                                              \
155         {                                                               \
156           if (unlikely(intg1+frac1 > (len)))                            \
157           {                                                             \
158             if (unlikely(intg1 > (len)))                                \
159             {                                                           \
160               intg1=(len);                                              \
161               frac1=0;                                                  \
162               error=E_DEC_OVERFLOW;                                     \
163             }                                                           \
164             else                                                        \
165             {                                                           \
166               frac1=(len)-intg1;                                        \
167               error=E_DEC_TRUNCATED;                                    \
168             }                                                           \
169           }                                                             \
170           else                                                          \
171             error=E_DEC_OK;                                             \
172         } while(0)
173 
174 #define ADD(to, from1, from2, carry)  /* assume carry <= 1 */           \
175         do                                                              \
176         {                                                               \
177           dec1 a=(from1)+(from2)+(carry);                               \
178           DBUG_ASSERT((carry) <= 1);                                    \
179           if (((carry)= a >= DIG_BASE)) /* no division here! */         \
180             a-=DIG_BASE;                                                \
181           (to)=a;                                                       \
182         } while(0)
183 
184 #define ADD2(to, from1, from2, carry)                                   \
185         do                                                              \
186         {                                                               \
187           dec2 a=((dec2)(from1))+(from2)+(carry);                       \
188           if (((carry)= a >= DIG_BASE))                                 \
189             a-=DIG_BASE;                                                \
190           if (unlikely(a >= DIG_BASE))                                  \
191           {                                                             \
192             a-=DIG_BASE;                                                \
193             carry++;                                                    \
194           }                                                             \
195           (to)=(dec1) a;                                                \
196         } while(0)
197 
198 #define SUB(to, from1, from2, carry) /* to=from1-from2 */               \
199         do                                                              \
200         {                                                               \
201           dec1 a=(from1)-(from2)-(carry);                               \
202           if (((carry)= a < 0))                                         \
203             a+=DIG_BASE;                                                \
204           (to)=a;                                                       \
205         } while(0)
206 
207 #define SUB2(to, from1, from2, carry) /* to=from1-from2 */              \
208         do                                                              \
209         {                                                               \
210           dec1 a=(from1)-(from2)-(carry);                               \
211           if (((carry)= a < 0))                                         \
212             a+=DIG_BASE;                                                \
213           if (unlikely(a < 0))                                          \
214           {                                                             \
215             a+=DIG_BASE;                                                \
216             carry++;                                                    \
217           }                                                             \
218           (to)=a;                                                       \
219         } while(0)
220 
221 
222 /*
223   This is a direct loop unrolling of code that used to look like this:
224   for (; *buf_beg < powers10[i--]; start++) ;
225 
226   @param   i    start index
227   @param   val  value to compare against list of powers of 10
228 
229   @retval  Number of leading zeroes that can be removed from fraction.
230 
231   @note Why unroll? To get rid of lots of compiler warnings [-Warray-bounds]
232         Nice bonus: unrolled code is significantly faster.
233  */
count_leading_zeroes(int i,dec1 val)234 static inline int count_leading_zeroes(int i, dec1 val)
235 {
236   int ret= 0;
237   switch (i)
238   {
239   /* @note Intentional fallthrough in all case labels */
240   case 9: if (val >= 1000000000) break; ++ret;  // Fall through.
241   case 8: if (val >= 100000000) break; ++ret;  // Fall through.
242   case 7: if (val >= 10000000) break; ++ret;  // Fall through.
243   case 6: if (val >= 1000000) break; ++ret;  // Fall through.
244   case 5: if (val >= 100000) break; ++ret;  // Fall through.
245   case 4: if (val >= 10000) break; ++ret;  // Fall through.
246   case 3: if (val >= 1000) break; ++ret;  // Fall through.
247   case 2: if (val >= 100) break; ++ret;  // Fall through.
248   case 1: if (val >= 10) break; ++ret;  // Fall through.
249   case 0: if (val >= 1) break; ++ret;  // Fall through.
250   default: { DBUG_ASSERT(FALSE); }
251   }
252   return ret;
253 }
254 
255 /*
256   This is a direct loop unrolling of code that used to look like this:
257   for (; *buf_end % powers10[i++] == 0; stop--) ;
258 
259   @param   i    start index
260   @param   val  value to compare against list of powers of 10
261 
262   @retval  Number of trailing zeroes that can be removed from fraction.
263 
264   @note Why unroll? To get rid of lots of compiler warnings [-Warray-bounds]
265         Nice bonus: unrolled code is significantly faster.
266  */
count_trailing_zeroes(int i,dec1 val)267 static inline int count_trailing_zeroes(int i, dec1 val)
268 {
269   int ret= 0;
270   switch(i)
271   {
272   /* @note Intentional fallthrough in all case labels */
273   case 0: if ((val % 1) != 0) break; ++ret;  // Fall through.
274   case 1: if ((val % 10) != 0) break; ++ret;  // Fall through.
275   case 2: if ((val % 100) != 0) break; ++ret;  // Fall through.
276   case 3: if ((val % 1000) != 0) break; ++ret;  // Fall through.
277   case 4: if ((val % 10000) != 0) break; ++ret;  // Fall through.
278   case 5: if ((val % 100000) != 0) break; ++ret;  // Fall through.
279   case 6: if ((val % 1000000) != 0) break; ++ret;  // Fall through.
280   case 7: if ((val % 10000000) != 0) break; ++ret;  // Fall through.
281   case 8: if ((val % 100000000) != 0) break; ++ret;  // Fall through.
282   case 9: if ((val % 1000000000) != 0) break; ++ret;  // Fall through.
283   default: { DBUG_ASSERT(FALSE); }
284   }
285   return ret;
286 }
287 
288 
289 /*
290   Get maximum value for given precision and scale
291 
292   SYNOPSIS
293     max_decimal()
294     precision/scale - see decimal_bin_size() below
295     to              - decimal where where the result will be stored
296                       to->buf and to->len must be set.
297 */
298 
max_decimal(int precision,int frac,decimal_t * to)299 void max_decimal(int precision, int frac, decimal_t *to)
300 {
301   int intpart;
302   dec1 *buf= to->buf;
303   DBUG_ASSERT(precision && precision >= frac);
304 
305   to->sign= 0;
306   if ((intpart= to->intg= (precision - frac)))
307   {
308     int firstdigits= intpart % DIG_PER_DEC1;
309     if (firstdigits)
310       *buf++= powers10[firstdigits] - 1; /* get 9 99 999 ... */
311     for(intpart/= DIG_PER_DEC1; intpart; intpart--)
312       *buf++= DIG_MAX;
313   }
314 
315   if ((to->frac= frac))
316   {
317     int lastdigits= frac % DIG_PER_DEC1;
318     for(frac/= DIG_PER_DEC1; frac; frac--)
319       *buf++= DIG_MAX;
320     if (lastdigits)
321       *buf= frac_max[lastdigits - 1];
322   }
323 }
324 
325 
remove_leading_zeroes(const decimal_t * from,int * intg_result)326 static dec1 *remove_leading_zeroes(const decimal_t *from, int *intg_result)
327 {
328   int intg= from->intg, i;
329   dec1 *buf0= from->buf;
330   i= ((intg - 1) % DIG_PER_DEC1) + 1;
331   while (intg > 0 && *buf0 == 0)
332   {
333     intg-= i;
334     i= DIG_PER_DEC1;
335     buf0++;
336   }
337   if (intg > 0)
338   {
339     intg-= count_leading_zeroes((intg - 1) % DIG_PER_DEC1, *buf0);
340     DBUG_ASSERT(intg > 0);
341   }
342   else
343     intg=0;
344   *intg_result= intg;
345   return buf0;
346 }
347 
348 
349 /*
350   Count actual length of fraction part (without ending zeroes)
351 
352   SYNOPSIS
353     decimal_actual_fraction()
354     from    number for processing
355 */
356 
decimal_actual_fraction(decimal_t * from)357 int decimal_actual_fraction(decimal_t *from)
358 {
359   int frac= from->frac, i;
360   dec1 *buf0= from->buf + ROUND_UP(from->intg) + ROUND_UP(frac) - 1;
361 
362   if (frac == 0)
363     return 0;
364 
365   i= ((frac - 1) % DIG_PER_DEC1 + 1);
366   while (frac > 0 && *buf0 == 0)
367   {
368     frac-= i;
369     i= DIG_PER_DEC1;
370     buf0--;
371   }
372   if (frac > 0)
373   {
374     frac-=
375       count_trailing_zeroes(DIG_PER_DEC1 - ((frac - 1) % DIG_PER_DEC1), *buf0);
376   }
377   return frac;
378 }
379 
380 
381 /*
382   Convert decimal to its printable string representation
383 
384   SYNOPSIS
385     decimal2string()
386       from            - value to convert
387       to              - points to buffer where string representation
388                         should be stored
389       *to_len         - in:  size of to buffer (incl. terminating '\0')
390                         out: length of the actually written string (excl. '\0')
391       fixed_precision - 0 if representation can be variable length and
392                         fixed_decimals will not be checked in this case.
393                         Put number as with fixed point position with this
394                         number of digits (sign counted and decimal point is
395                         counted)
396       fixed_decimals  - number digits after point.
397       filler          - character to fill gaps in case of fixed_precision > 0
398 
399   RETURN VALUE
400     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
401 */
402 
decimal2string(const decimal_t * from,char * to,int * to_len,int fixed_precision,int fixed_decimals,char filler)403 int decimal2string(const decimal_t *from, char *to, int *to_len,
404                    int fixed_precision, int fixed_decimals,
405                    char filler)
406 {
407   /* {intg_len, frac_len} output widths; {intg, frac} places in input */
408   int len, intg, frac= from->frac, i, intg_len, frac_len, fill;
409   /* number digits before decimal point */
410   int fixed_intg= (fixed_precision ?
411                    (fixed_precision - fixed_decimals) : 0);
412   int error=E_DEC_OK;
413   char *s=to;
414   dec1 *buf, *buf0=from->buf, tmp;
415 
416   DBUG_ASSERT(*to_len >= 2+from->sign);
417 
418   /* removing leading zeroes */
419   buf0= remove_leading_zeroes(from, &intg);
420   if (unlikely(intg+frac==0))
421   {
422     intg=1;
423     tmp=0;
424     buf0=&tmp;
425   }
426 
427   if (!(intg_len= fixed_precision ? fixed_intg : intg))
428     intg_len= 1;
429   frac_len= fixed_precision ? fixed_decimals : frac;
430   len= from->sign + intg_len + MY_TEST(frac) + frac_len;
431   if (fixed_precision)
432   {
433     if (frac > fixed_decimals)
434     {
435       error= E_DEC_TRUNCATED;
436       frac= fixed_decimals;
437     }
438     if (intg > fixed_intg)
439     {
440       error= E_DEC_OVERFLOW;
441       intg= fixed_intg;
442     }
443   }
444   else if (unlikely(len > --*to_len)) /* reserve one byte for \0 */
445   {
446     int j= len - *to_len;             /* excess printable chars */
447     error= (frac && j <= frac + 1) ? E_DEC_TRUNCATED : E_DEC_OVERFLOW;
448 
449     /*
450       If we need to cut more places than frac is wide, we'll end up
451       dropping the decimal point as well.  Account for this.
452     */
453     if (frac && j >= frac + 1)
454       j--;
455 
456     if (j > frac)
457     {
458       intg_len= intg-= j-frac;
459       frac= 0;
460     }
461     else
462       frac-=j;
463     frac_len= frac;
464     len= from->sign + intg_len + MY_TEST(frac) + frac_len;
465   }
466   *to_len= len;
467   s[len]= 0;
468 
469   if (from->sign)
470     *s++='-';
471 
472   if (frac)
473   {
474     char *s1= s + intg_len;
475     fill= frac_len - frac;
476     buf=buf0+ROUND_UP(intg);
477     *s1++='.';
478     for (; frac>0; frac-=DIG_PER_DEC1)
479     {
480       dec1 x=*buf++;
481       for (i= MY_MIN(frac, DIG_PER_DEC1); i; i--)
482       {
483         dec1 y=x/DIG_MASK;
484         *s1++='0'+(uchar)y;
485         x-=y*DIG_MASK;
486         x*=10;
487       }
488     }
489     for(; fill > 0; fill--)
490       *s1++=filler;
491   }
492 
493   fill= intg_len - intg;
494   if (intg == 0)
495     fill--; /* symbol 0 before digital point */
496   for(; fill > 0; fill--)
497     *s++=filler;
498   if (intg)
499   {
500     s+=intg;
501     for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
502     {
503       dec1 x=*--buf;
504       for (i= MY_MIN(intg, DIG_PER_DEC1); i; i--)
505       {
506         dec1 y=x/10;
507         *--s='0'+(uchar)(x-y*10);
508         x=y;
509       }
510     }
511   }
512   else
513     *s= '0';
514 
515   return error;
516 }
517 
518 
519 /*
520   Return bounds of decimal digits in the number
521 
522   SYNOPSIS
523     digits_bounds()
524       from         - decimal number for processing
525       start_result - index (from 0 ) of first decimal digits will
526                      be written by this address
527       end_result   - index of position just after last decimal digit
528                      be written by this address
529 */
530 
digits_bounds(decimal_t * from,int * start_result,int * end_result)531 static void digits_bounds(decimal_t *from, int *start_result, int *end_result)
532 {
533   int start, stop, i;
534   dec1 *buf_beg= from->buf;
535   dec1 *end= from->buf + ROUND_UP(from->intg) + ROUND_UP(from->frac);
536   dec1 *buf_end= end - 1;
537 
538   /* find non-zero digit from number begining */
539   while (buf_beg < end && *buf_beg == 0)
540     buf_beg++;
541 
542   if (buf_beg >= end)
543   {
544     /* it is zero */
545     *start_result= *end_result= 0;
546     return;
547   }
548 
549   /* find non-zero decimal digit from number begining */
550   if (buf_beg == from->buf && from->intg)
551   {
552     start= DIG_PER_DEC1 - (i= ((from->intg-1) % DIG_PER_DEC1 + 1));
553     i--;
554   }
555   else
556   {
557     i= DIG_PER_DEC1 - 1;
558     start= (int) ((buf_beg - from->buf) * DIG_PER_DEC1);
559   }
560   if (buf_beg < end)
561     start+= count_leading_zeroes(i, *buf_beg);
562 
563   *start_result= start; /* index of first decimal digit (from 0) */
564 
565   /* find non-zero digit at the end */
566   while (buf_end > buf_beg  && *buf_end == 0)
567     buf_end--;
568   /* find non-zero decimal digit from the end */
569   if (buf_end == end - 1 && from->frac)
570   {
571     stop= (int) (((buf_end - from->buf) * DIG_PER_DEC1 +
572            (i= ((from->frac - 1) % DIG_PER_DEC1 + 1))));
573     i= DIG_PER_DEC1 - i + 1;
574   }
575   else
576   {
577     stop= (int) ((buf_end - from->buf + 1) * DIG_PER_DEC1);
578     i= 1;
579   }
580   stop-= count_trailing_zeroes(i, *buf_end);
581   *end_result= stop; /* index of position after last decimal digit (from 0) */
582 }
583 
584 
585 /*
586   Left shift for alignment of data in buffer
587 
588   SYNOPSIS
589     do_mini_left_shift()
590     dec     pointer to decimal number which have to be shifted
591     shift   number of decimal digits on which it should be shifted
592     beg/end bounds of decimal digits (see digits_bounds())
593 
594   NOTE
595     Result fitting in the buffer should be garanted.
596     'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
597 */
598 
do_mini_left_shift(decimal_t * dec,int shift,int beg,int last)599 void do_mini_left_shift(decimal_t *dec, int shift, int beg, int last)
600 {
601   dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
602   dec1 *end= dec->buf + ROUND_UP(last) - 1;
603   int c_shift= DIG_PER_DEC1 - shift;
604   DBUG_ASSERT(from >= dec->buf);
605   DBUG_ASSERT(end < dec->buf + dec->len);
606   if (beg % DIG_PER_DEC1 < shift)
607     *(from - 1)= (*from) / powers10[c_shift];
608   for(; from < end; from++)
609     *from= ((*from % powers10[c_shift]) * powers10[shift] +
610             (*(from + 1)) / powers10[c_shift]);
611   *from= (*from % powers10[c_shift]) * powers10[shift];
612 }
613 
614 
615 /*
616   Right shift for alignment of data in buffer
617 
618   SYNOPSIS
619     do_mini_left_shift()
620     dec     pointer to decimal number which have to be shifted
621     shift   number of decimal digits on which it should be shifted
622     beg/end bounds of decimal digits (see digits_bounds())
623 
624   NOTE
625     Result fitting in the buffer should be garanted.
626     'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
627 */
628 
do_mini_right_shift(decimal_t * dec,int shift,int beg,int last)629 void do_mini_right_shift(decimal_t *dec, int shift, int beg, int last)
630 {
631   dec1 *from= dec->buf + ROUND_UP(last) - 1;
632   dec1 *end= dec->buf + ROUND_UP(beg + 1) - 1;
633   int c_shift= DIG_PER_DEC1 - shift;
634   DBUG_ASSERT(from < dec->buf + dec->len);
635   DBUG_ASSERT(end >= dec->buf);
636   if (DIG_PER_DEC1 - ((last - 1) % DIG_PER_DEC1 + 1) < shift)
637     *(from + 1)= (*from % powers10[shift]) * powers10[c_shift];
638   for(; from > end; from--)
639     *from= (*from / powers10[shift] +
640             (*(from - 1) % powers10[shift]) * powers10[c_shift]);
641   *from= *from / powers10[shift];
642 }
643 
644 
645 /*
646   Shift of decimal digits in given number (with rounding if it need)
647 
648   SYNOPSIS
649     decimal_shift()
650     dec       number to be shifted
651     shift     number of decimal positions
652               shift > 0 means shift to left shift
653               shift < 0 meand right shift
654   NOTE
655     In fact it is multipling on 10^shift.
656   RETURN
657     E_DEC_OK          OK
658     E_DEC_OVERFLOW    operation lead to overflow, number is untoched
659     E_DEC_TRUNCATED   number was rounded to fit into buffer
660 */
661 
decimal_shift(decimal_t * dec,int shift)662 int decimal_shift(decimal_t *dec, int shift)
663 {
664   /* index of first non zero digit (all indexes from 0) */
665   int beg;
666   /* index of position after last decimal digit */
667   int end;
668   /* index of digit position just after point */
669   int point= ROUND_UP(dec->intg) * DIG_PER_DEC1;
670   /* new point position */
671   int new_point= point + shift;
672   /* number of digits in result */
673   int digits_int, digits_frac;
674   /* length of result and new fraction in big digits*/
675   int new_len, new_frac_len;
676   /* return code */
677   int err= E_DEC_OK;
678   int new_front;
679 
680   if (shift == 0)
681     return E_DEC_OK;
682 
683   digits_bounds(dec, &beg, &end);
684 
685   if (beg == end)
686   {
687     decimal_make_zero(dec);
688     return E_DEC_OK;
689   }
690 
691   digits_int= new_point - beg;
692   set_if_bigger(digits_int, 0);
693   digits_frac= end - new_point;
694   set_if_bigger(digits_frac, 0);
695 
696   if ((new_len= ROUND_UP(digits_int) + (new_frac_len= ROUND_UP(digits_frac))) >
697       dec->len)
698   {
699     int lack= new_len - dec->len;
700     int diff;
701 
702     if (new_frac_len < lack)
703       return E_DEC_OVERFLOW; /* lack more then we have in fraction */
704 
705     /* cat off fraction part to allow new number to fit in our buffer */
706     err= E_DEC_TRUNCATED;
707     new_frac_len-= lack;
708     diff= digits_frac - (new_frac_len * DIG_PER_DEC1);
709     /* Make rounding method as parameter? */
710     decimal_round(dec, dec, end - point - diff, HALF_UP);
711     end-= diff;
712     digits_frac= new_frac_len * DIG_PER_DEC1;
713 
714     if (end <= beg)
715     {
716       /*
717         we lost all digits (they will be shifted out of buffer), so we can
718         just return 0
719       */
720       decimal_make_zero(dec);
721       return E_DEC_TRUNCATED;
722     }
723   }
724 
725   if (shift % DIG_PER_DEC1)
726   {
727     int l_mini_shift, r_mini_shift, mini_shift;
728     int do_left;
729     /*
730       Calculate left/right shift to align decimal digits inside our bug
731       digits correctly
732     */
733     if (shift > 0)
734     {
735       l_mini_shift= shift % DIG_PER_DEC1;
736       r_mini_shift= DIG_PER_DEC1 - l_mini_shift;
737       /*
738         It is left shift so prefer left shift, but if we have not place from
739         left, we have to have it from right, because we checked length of
740         result
741       */
742       do_left= l_mini_shift <= beg;
743       DBUG_ASSERT(do_left || (dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
744     }
745     else
746     {
747       r_mini_shift= (-shift) % DIG_PER_DEC1;
748       l_mini_shift= DIG_PER_DEC1 - r_mini_shift;
749       /* see comment above */
750       do_left= !((dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
751       DBUG_ASSERT(!do_left || l_mini_shift <= beg);
752     }
753     if (do_left)
754     {
755       do_mini_left_shift(dec, l_mini_shift, beg, end);
756       mini_shift= -l_mini_shift;
757     }
758     else
759     {
760       do_mini_right_shift(dec, r_mini_shift, beg, end);
761       mini_shift= r_mini_shift;
762     }
763     new_point+= mini_shift;
764     /*
765       If number is shifted and correctly aligned in buffer we can
766       finish
767     */
768     if (!(shift+= mini_shift) && (new_point - digits_int) < DIG_PER_DEC1)
769     {
770       dec->intg= digits_int;
771       dec->frac= digits_frac;
772       return err;                 /* already shifted as it should be */
773     }
774     beg+= mini_shift;
775     end+= mini_shift;
776   }
777 
778   /* if new 'decimal front' is in first digit, we do not need move digits */
779   if ((new_front= (new_point - digits_int)) >= DIG_PER_DEC1 ||
780       new_front < 0)
781   {
782     /* need to move digits */
783     int d_shift;
784     dec1 *to, *barier;
785     if (new_front > 0)
786     {
787       /* move left */
788       d_shift= new_front / DIG_PER_DEC1;
789       to= dec->buf + (ROUND_UP(beg + 1) - 1 - d_shift);
790       barier= dec->buf + (ROUND_UP(end) - 1 - d_shift);
791       DBUG_ASSERT(to >= dec->buf);
792       DBUG_ASSERT(barier + d_shift < dec->buf + dec->len);
793       for(; to <= barier; to++)
794         *to= *(to + d_shift);
795       for(barier+= d_shift; to <= barier; to++)
796         *to= 0;
797       d_shift= -d_shift;
798     }
799     else
800     {
801       /* move right */
802       d_shift= (1 - new_front) / DIG_PER_DEC1;
803       to= dec->buf + ROUND_UP(end) - 1 + d_shift;
804       barier= dec->buf + ROUND_UP(beg + 1) - 1 + d_shift;
805       DBUG_ASSERT(to < dec->buf + dec->len);
806       DBUG_ASSERT(barier - d_shift >= dec->buf);
807       for(; to >= barier; to--)
808         *to= *(to - d_shift);
809       for(barier-= d_shift; to >= barier; to--)
810         *to= 0;
811     }
812     d_shift*= DIG_PER_DEC1;
813     beg+= d_shift;
814     end+= d_shift;
815     new_point+= d_shift;
816   }
817 
818   /*
819     If there are gaps then fill ren with 0.
820 
821     Only one of following 'for' loops will work becouse beg <= end
822   */
823   beg= ROUND_UP(beg + 1) - 1;
824   end= ROUND_UP(end) - 1;
825   DBUG_ASSERT(new_point >= 0);
826 
827   /* We don't want negative new_point below */
828   if (new_point != 0)
829     new_point= ROUND_UP(new_point) - 1;
830 
831   if (new_point > end)
832   {
833     do
834     {
835       dec->buf[new_point]=0;
836     } while (--new_point > end);
837   }
838   else
839   {
840     for (; new_point < beg; new_point++)
841       dec->buf[new_point]= 0;
842   }
843   dec->intg= digits_int;
844   dec->frac= digits_frac;
845   return err;
846 }
847 
848 
849 /*
850   Convert string to decimal
851 
852   SYNOPSIS
853     internal_str2decl()
854       from    - value to convert. Doesn't have to be \0 terminated!
855       to      - decimal where where the result will be stored
856                 to->buf and to->len must be set.
857       end     - Pointer to pointer to end of string. Will on return be
858 		set to the char after the last used character
859       fixed   - use to->intg, to->frac as limits for input number
860 
861   NOTE
862     to->intg and to->frac can be modified even when fixed=1
863     (but only decreased, in this case)
864 
865   RETURN VALUE
866     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_BAD_NUM/E_DEC_OOM
867     In case of E_DEC_FATAL_ERROR *to is set to decimal zero
868     (to make error handling easier)
869 */
870 
871 int
internal_str2dec(const char * from,decimal_t * to,char ** end,my_bool fixed)872 internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed)
873 {
874   const char *s= from, *s1, *endp, *end_of_string= *end;
875   int i, intg, frac, error, intg1, frac1;
876   dec1 x,*buf;
877   sanity(to);
878 
879   error= E_DEC_BAD_NUM;                         /* In case of bad number */
880   while (s < end_of_string && my_isspace(&my_charset_latin1, *s))
881     s++;
882   if (s == end_of_string)
883     goto fatal_error;
884 
885   if ((to->sign= (*s == '-')))
886     s++;
887   else if (*s == '+')
888     s++;
889 
890   s1=s;
891   while (s < end_of_string && my_isdigit(&my_charset_latin1, *s))
892     s++;
893   intg= (int) (s-s1);
894   if (s < end_of_string && *s=='.')
895   {
896     endp= s+1;
897     while (endp < end_of_string && my_isdigit(&my_charset_latin1, *endp))
898       endp++;
899     frac= (int) (endp - s - 1);
900   }
901   else
902   {
903     frac= 0;
904     endp= s;
905   }
906 
907   *end= (char*) endp;
908 
909   if (frac+intg == 0)
910     goto fatal_error;
911 
912   error= 0;
913   if (fixed)
914   {
915     if (frac > to->frac)
916     {
917       error=E_DEC_TRUNCATED;
918       frac=to->frac;
919     }
920     if (intg > to->intg)
921     {
922       error=E_DEC_OVERFLOW;
923       intg=to->intg;
924     }
925     intg1=ROUND_UP(intg);
926     frac1=ROUND_UP(frac);
927     if (intg1+frac1 > to->len)
928     {
929       error= E_DEC_OOM;
930       goto fatal_error;
931     }
932   }
933   else
934   {
935     intg1=ROUND_UP(intg);
936     frac1=ROUND_UP(frac);
937     FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
938     if (unlikely(error))
939     {
940       frac=frac1*DIG_PER_DEC1;
941       if (error == E_DEC_OVERFLOW)
942         intg=intg1*DIG_PER_DEC1;
943     }
944   }
945   /* Error is guranteed to be set here */
946   to->intg=intg;
947   to->frac=frac;
948 
949   buf=to->buf+intg1;
950   s1=s;
951 
952   for (x=0, i=0; intg; intg--)
953   {
954     x+= (*--s - '0')*powers10[i];
955 
956     if (unlikely(++i == DIG_PER_DEC1))
957     {
958       *--buf=x;
959       x=0;
960       i=0;
961     }
962   }
963   if (i)
964     *--buf=x;
965 
966   buf=to->buf+intg1;
967   for (x=0, i=0; frac; frac--)
968   {
969     x= (*++s1 - '0') + x*10;
970 
971     if (unlikely(++i == DIG_PER_DEC1))
972     {
973       *buf++=x;
974       x=0;
975       i=0;
976     }
977   }
978   if (i)
979     *buf=x*powers10[DIG_PER_DEC1-i];
980 
981   /* Handle exponent */
982   if (endp+1 < end_of_string && (*endp == 'e' || *endp == 'E'))
983   {
984     int str_error;
985     longlong exponent= my_strtoll10(endp+1, (char**) &end_of_string,
986                                     &str_error);
987 
988     if (end_of_string != endp +1)               /* If at least one digit */
989     {
990       *end= (char*) end_of_string;
991       if (str_error > 0)
992       {
993         error= E_DEC_BAD_NUM;
994         goto fatal_error;
995       }
996       if (exponent > INT_MAX/2 || (str_error == 0 && exponent < 0))
997       {
998         error= E_DEC_OVERFLOW;
999         goto fatal_error;
1000       }
1001       if (exponent < INT_MIN/2 && error != E_DEC_OVERFLOW)
1002       {
1003         error= E_DEC_TRUNCATED;
1004         goto fatal_error;
1005       }
1006       if (error != E_DEC_OVERFLOW)
1007         error= decimal_shift(to, (int) exponent);
1008     }
1009   }
1010   /* Avoid returning negative zero, cfr. decimal_cmp() */
1011   if (to->sign && decimal_is_zero(to))
1012     to->sign= FALSE;
1013   return error;
1014 
1015 fatal_error:
1016   decimal_make_zero(to);
1017   return error;
1018 }
1019 
1020 
1021 /*
1022   Convert decimal to double
1023 
1024   SYNOPSIS
1025     decimal2double()
1026       from    - value to convert
1027       to      - result will be stored there
1028 
1029   RETURN VALUE
1030     E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1031 */
1032 
decimal2double(const decimal_t * from,double * to)1033 int decimal2double(const decimal_t *from, double *to)
1034 {
1035   char strbuf[FLOATING_POINT_BUFFER], *end;
1036   int len= sizeof(strbuf);
1037   int rc, error;
1038 
1039   rc = decimal2string(from, strbuf, &len, 0, 0, 0);
1040   end= strbuf + len;
1041 
1042   DBUG_PRINT("info", ("interm.: %s", strbuf));
1043 
1044   *to= my_strtod(strbuf, &end, &error);
1045 
1046   DBUG_PRINT("info", ("result: %f", *to));
1047 
1048   return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
1049 }
1050 
1051 /*
1052   Convert double to decimal
1053 
1054   SYNOPSIS
1055     double2decimal()
1056       from    - value to convert
1057       to      - result will be stored there
1058 
1059   RETURN VALUE
1060     E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1061 */
1062 
double2decimal(double from,decimal_t * to)1063 int double2decimal(double from, decimal_t *to)
1064 {
1065   char buff[FLOATING_POINT_BUFFER], *end;
1066   int res;
1067   DBUG_ENTER("double2decimal");
1068   end= buff + my_gcvt(from, MY_GCVT_ARG_DOUBLE, (int)sizeof(buff) - 1, buff, NULL);
1069   res= string2decimal(buff, to, &end);
1070   DBUG_PRINT("exit", ("res: %d", res));
1071   DBUG_RETURN(res);
1072 }
1073 
1074 
ull2dec(ulonglong from,decimal_t * to)1075 static int ull2dec(ulonglong from, decimal_t *to)
1076 {
1077   int intg1;
1078   int error= E_DEC_OK;
1079   ulonglong x= from;
1080   dec1 *buf;
1081 
1082   sanity(to);
1083 
1084   if (from == 0)
1085     intg1= 1;
1086   else
1087   {
1088     /* Count the number of decimal_digit_t's we need. */
1089     for (intg1= 0; from != 0; intg1++, from/= DIG_BASE)
1090       ;
1091   }
1092   if (unlikely(intg1 > to->len))
1093   {
1094     intg1= to->len;
1095     error= E_DEC_OVERFLOW;
1096   }
1097   to->frac= 0;
1098   to->intg= intg1 * DIG_PER_DEC1;
1099 
1100   for (buf= to->buf + intg1; intg1; intg1--)
1101   {
1102     ulonglong y= x / DIG_BASE;
1103     *--buf=(dec1)(x - y * DIG_BASE);
1104     x= y;
1105   }
1106   return error;
1107 }
1108 
ulonglong2decimal(ulonglong from,decimal_t * to)1109 int ulonglong2decimal(ulonglong from, decimal_t *to)
1110 {
1111   to->sign=0;
1112   return ull2dec(from, to);
1113 }
1114 
longlong2decimal(longlong from,decimal_t * to)1115 int longlong2decimal(longlong from, decimal_t *to)
1116 {
1117   if ((to->sign= from < 0))
1118     return ull2dec(-from, to);
1119   return ull2dec(from, to);
1120 }
1121 
decimal2ulonglong(decimal_t * from,ulonglong * to)1122 int decimal2ulonglong(decimal_t *from, ulonglong *to)
1123 {
1124   dec1 *buf=from->buf;
1125   ulonglong x=0;
1126   int intg, frac;
1127 
1128   if (from->sign)
1129   {
1130       *to=0ULL;
1131       return E_DEC_OVERFLOW;
1132   }
1133 
1134   for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1135   {
1136     ulonglong y=x;
1137     x=x*DIG_BASE + *buf++;
1138     if (unlikely(y > ((ulonglong) ULLONG_MAX/DIG_BASE) || x < y))
1139     {
1140       *to=ULLONG_MAX;
1141       return E_DEC_OVERFLOW;
1142     }
1143   }
1144   *to=x;
1145   for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1146     if (*buf++)
1147       return E_DEC_TRUNCATED;
1148   return E_DEC_OK;
1149 }
1150 
decimal2longlong(decimal_t * from,longlong * to)1151 int decimal2longlong(decimal_t *from, longlong *to)
1152 {
1153   dec1 *buf=from->buf;
1154   longlong x=0;
1155   int intg, frac;
1156 
1157   for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1158   {
1159     longlong y=x;
1160     /*
1161       Attention: trick!
1162       we're calculating -|from| instead of |from| here
1163       because |LLONG_MIN| > LLONG_MAX
1164       so we can convert -9223372036854775808 correctly
1165     */
1166     x=x*DIG_BASE - *buf++;
1167     if (unlikely(y < (LLONG_MIN/DIG_BASE) || x > y))
1168     {
1169       /*
1170         the decimal is bigger than any possible integer
1171         return border integer depending on the sign
1172       */
1173       *to= from->sign ? LLONG_MIN : LLONG_MAX;
1174       return E_DEC_OVERFLOW;
1175     }
1176   }
1177   /* boundary case: 9223372036854775808 */
1178   if (unlikely(from->sign==0 && x == LLONG_MIN))
1179   {
1180     *to= LLONG_MAX;
1181     return E_DEC_OVERFLOW;
1182   }
1183 
1184   *to=from->sign ? x : -x;
1185   for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1186     if (*buf++)
1187       return E_DEC_TRUNCATED;
1188   return E_DEC_OK;
1189 }
1190 
1191 
1192 #define LLDIV_MIN -1000000000000000000LL
1193 #define LLDIV_MAX  1000000000000000000LL
1194 
1195 /**
1196   Convert decimal value to lldiv_t value.
1197   @param      from  The decimal value to convert from.
1198   @param OUT  to    The lldiv_t variable to convert to.
1199   @return           0 on success, error code on error.
1200 */
decimal2lldiv_t(const decimal_t * from,lldiv_t * to)1201 int decimal2lldiv_t(const decimal_t *from, lldiv_t *to)
1202 {
1203   int int_part= ROUND_UP(from->intg);
1204   int frac_part= ROUND_UP(from->frac);
1205   if (int_part > 2)
1206   {
1207     to->rem= 0;
1208     to->quot= from->sign ? LLDIV_MIN : LLDIV_MAX;
1209     return E_DEC_OVERFLOW;
1210   }
1211   if (int_part == 2)
1212     to->quot= ((longlong) from->buf[0]) * DIG_BASE + from->buf[1];
1213   else if (int_part == 1)
1214     to->quot= from->buf[0];
1215   else
1216     to->quot= 0;
1217   to->rem= frac_part ? from->buf[int_part] : 0;
1218   if (from->sign)
1219   {
1220     to->quot= -to->quot;
1221     to->rem= -to->rem;
1222   }
1223   return 0;
1224 }
1225 
1226 
1227 /**
1228   Convert double value to lldiv_t valie.
1229   @param     from The double value to convert from.
1230   @param OUT to   The lldit_t variable to convert to.
1231   @return         0 on success, error code on error.
1232 
1233   Integer part goes into lld.quot.
1234   Fractional part multiplied to 1000000000 (10^9) goes to lld.rem.
1235   Typically used in datetime calculations to split seconds
1236   and nanoseconds.
1237 */
double2lldiv_t(double nr,lldiv_t * lld)1238 int double2lldiv_t(double nr, lldiv_t *lld)
1239 {
1240   if (nr > LLDIV_MAX)
1241   {
1242     lld->quot= LLDIV_MAX;
1243     lld->rem= 0;
1244     return E_DEC_OVERFLOW;
1245   }
1246   else if (nr < LLDIV_MIN)
1247   {
1248     lld->quot= LLDIV_MIN;
1249     lld->rem= 0;
1250     return E_DEC_OVERFLOW;
1251   }
1252   /* Truncate fractional part toward zero and store into "quot" */
1253   lld->quot= (longlong) (nr > 0 ? floor(nr) : ceil(nr));
1254   /* Multiply reminder to 10^9 and store into "rem" */
1255   lld->rem= (longlong) rint((nr - (double) lld->quot) * 1000000000);
1256   /*
1257     Sometimes the expression "(double) 0.999999999xxx * (double) 10e9"
1258     gives 1,000,000,000 instead of 999,999,999 due to lack of double precision.
1259     The callers do not expect lld->rem to be greater than 999,999,999.
1260     Let's catch this corner case and put the "nanounit" (e.g. nanosecond)
1261     value in ldd->rem back into the valid range.
1262   */
1263   if (lld->rem > 999999999LL)
1264     lld->rem= 999999999LL;
1265   else if (lld->rem < -999999999LL)
1266     lld->rem= -999999999LL;
1267   return E_DEC_OK;
1268 }
1269 
1270 
1271 
1272 /*
1273   Convert decimal to its binary fixed-length representation
1274   two representations of the same length can be compared with memcmp
1275   with the correct -1/0/+1 result
1276 
1277   SYNOPSIS
1278     decimal2bin()
1279       from    - value to convert
1280       to      - points to buffer where string representation should be stored
1281       precision/scale - see decimal_bin_size() below
1282 
1283   NOTE
1284     the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1285 
1286   RETURN VALUE
1287     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1288 
1289   DESCRIPTION
1290     for storage decimal numbers are converted to the "binary" format.
1291 
1292     This format has the following properties:
1293       1. length of the binary representation depends on the {precision, scale}
1294       as provided by the caller and NOT on the intg/frac of the decimal to
1295       convert.
1296       2. binary representations of the same {precision, scale} can be compared
1297       with memcmp - with the same result as decimal_cmp() of the original
1298       decimals (not taking into account possible precision loss during
1299       conversion).
1300 
1301     This binary format is as follows:
1302       1. First the number is converted to have a requested precision and scale.
1303       2. Every full DIG_PER_DEC1 digits of intg part are stored in 4 bytes
1304          as is
1305       3. The first intg % DIG_PER_DEC1 digits are stored in the reduced
1306          number of bytes (enough bytes to store this number of digits -
1307          see dig2bytes)
1308       4. same for frac - full decimal_digit_t's are stored as is,
1309          the last frac % DIG_PER_DEC1 digits - in the reduced number of bytes.
1310       5. If the number is negative - every byte is inversed.
1311       5. The very first bit of the resulting byte array is inverted (because
1312          memcmp compares unsigned bytes, see property 2 above)
1313 
1314     Example:
1315 
1316       1234567890.1234
1317 
1318     internally is represented as 3 decimal_digit_t's
1319 
1320       1 234567890 123400000
1321 
1322     (assuming we want a binary representation with precision=14, scale=4)
1323     in hex it's
1324 
1325       00-00-00-01  0D-FB-38-D2  07-5A-EF-40
1326 
1327     now, middle decimal_digit_t is full - it stores 9 decimal digits. It goes
1328     into binary representation as is:
1329 
1330 
1331       ...........  0D-FB-38-D2 ............
1332 
1333     First decimal_digit_t has only one decimal digit. We can store one digit in
1334     one byte, no need to waste four:
1335 
1336                 01 0D-FB-38-D2 ............
1337 
1338     now, last digit. It's 123400000. We can store 1234 in two bytes:
1339 
1340                 01 0D-FB-38-D2 04-D2
1341 
1342     So, we've packed 12 bytes number in 7 bytes.
1343     And now we invert the highest bit to get the final result:
1344 
1345                 81 0D FB 38 D2 04 D2
1346 
1347     And for -1234567890.1234 it would be
1348 
1349                 7E F2 04 C7 2D FB 2D
1350 */
decimal2bin(decimal_t * from,uchar * to,int precision,int frac)1351 int decimal2bin(decimal_t *from, uchar *to, int precision, int frac)
1352 {
1353   dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
1354   int error=E_DEC_OK, intg=precision-frac,
1355       isize1, intg1, intg1x, from_intg,
1356       intg0=intg/DIG_PER_DEC1,
1357       frac0=frac/DIG_PER_DEC1,
1358       intg0x=intg-intg0*DIG_PER_DEC1,
1359       frac0x=frac-frac0*DIG_PER_DEC1,
1360       frac1=from->frac/DIG_PER_DEC1,
1361       frac1x=from->frac-frac1*DIG_PER_DEC1,
1362       isize0=intg0*sizeof(dec1)+dig2bytes[intg0x],
1363       fsize0=frac0*sizeof(dec1)+dig2bytes[frac0x],
1364       fsize1=frac1*sizeof(dec1)+dig2bytes[frac1x];
1365   const int orig_isize0= isize0;
1366   const int orig_fsize0= fsize0;
1367   uchar *orig_to= to;
1368 
1369   buf1= remove_leading_zeroes(from, &from_intg);
1370 
1371   if (unlikely(from_intg+fsize1==0))
1372   {
1373     mask=0; /* just in case */
1374     intg=1;
1375     buf1=&mask;
1376   }
1377 
1378   intg1=from_intg/DIG_PER_DEC1;
1379   intg1x=from_intg-intg1*DIG_PER_DEC1;
1380   isize1=intg1*sizeof(dec1)+dig2bytes[intg1x];
1381 
1382   if (intg < from_intg)
1383   {
1384     buf1+=intg1-intg0+(intg1x>0)-(intg0x>0);
1385     intg1=intg0; intg1x=intg0x;
1386     error=E_DEC_OVERFLOW;
1387   }
1388   else if (isize0 > isize1)
1389   {
1390     while (isize0-- > isize1)
1391       *to++= (char)mask;
1392   }
1393   if (fsize0 < fsize1)
1394   {
1395     frac1=frac0; frac1x=frac0x;
1396     error=E_DEC_TRUNCATED;
1397   }
1398   else if (fsize0 > fsize1 && frac1x)
1399   {
1400     if (frac0 == frac1)
1401     {
1402       frac1x=frac0x;
1403       fsize0= fsize1;
1404     }
1405     else
1406     {
1407       frac1++;
1408       frac1x=0;
1409     }
1410   }
1411 
1412   /* intg1x part */
1413   if (intg1x)
1414   {
1415     int i=dig2bytes[intg1x];
1416     dec1 x=(*buf1++ % powers10[intg1x]) ^ mask;
1417     switch (i)
1418     {
1419       case 1: mi_int1store(to, x); break;
1420       case 2: mi_int2store(to, x); break;
1421       case 3: mi_int3store(to, x); break;
1422       case 4: mi_int4store(to, x); break;
1423       default: DBUG_ASSERT(0);
1424     }
1425     to+=i;
1426   }
1427 
1428   /* intg1+frac1 part */
1429   for (stop1=buf1+intg1+frac1; buf1 < stop1; to+=sizeof(dec1))
1430   {
1431     dec1 x=*buf1++ ^ mask;
1432     DBUG_ASSERT(sizeof(dec1) == 4);
1433     mi_int4store(to, x);
1434   }
1435 
1436   /* frac1x part */
1437   if (frac1x)
1438   {
1439     dec1 x;
1440     int i=dig2bytes[frac1x],
1441         lim=(frac1 < frac0 ? DIG_PER_DEC1 : frac0x);
1442     while (frac1x < lim && dig2bytes[frac1x] == i)
1443       frac1x++;
1444     x=(*buf1 / powers10[DIG_PER_DEC1 - frac1x]) ^ mask;
1445     switch (i)
1446     {
1447       case 1: mi_int1store(to, x); break;
1448       case 2: mi_int2store(to, x); break;
1449       case 3: mi_int3store(to, x); break;
1450       case 4: mi_int4store(to, x); break;
1451       default: DBUG_ASSERT(0);
1452     }
1453     to+=i;
1454   }
1455   if (fsize0 > fsize1)
1456   {
1457     uchar *to_end= orig_to + orig_fsize0 + orig_isize0;
1458 
1459     while (fsize0-- > fsize1 && to < to_end)
1460       *to++= (uchar)mask;
1461   }
1462   orig_to[0]^= 0x80;
1463 
1464   /* Check that we have written the whole decimal and nothing more */
1465   DBUG_ASSERT(to == orig_to + orig_fsize0 + orig_isize0);
1466   return error;
1467 }
1468 
1469 /*
1470   Restores decimal from its binary fixed-length representation
1471 
1472   SYNOPSIS
1473     bin2decimal()
1474       from    - value to convert
1475       to      - result
1476       precision/scale - see decimal_bin_size() below
1477 
1478   NOTE
1479     see decimal2bin()
1480     the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1481 
1482   RETURN VALUE
1483     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1484 */
1485 
bin2decimal(const uchar * from,decimal_t * to,int precision,int scale)1486 int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale)
1487 {
1488   int error=E_DEC_OK, intg=precision-scale,
1489       intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1490       intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1,
1491       intg1=intg0+(intg0x>0), frac1=frac0+(frac0x>0);
1492   dec1 *buf=to->buf, mask=(*from & 0x80) ? 0 : -1;
1493   const uchar *stop;
1494   uchar *d_copy;
1495   int bin_size= decimal_bin_size(precision, scale);
1496 
1497   sanity(to);
1498   d_copy= (uchar*) my_alloca(bin_size);
1499   memcpy(d_copy, from, bin_size);
1500   d_copy[0]^= 0x80;
1501   from= d_copy;
1502 
1503   FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
1504   if (unlikely(error))
1505   {
1506     if (intg1 < intg0+(intg0x>0))
1507     {
1508       from+=dig2bytes[intg0x]+sizeof(dec1)*(intg0-intg1);
1509       frac0=frac0x=intg0x=0;
1510       intg0=intg1;
1511     }
1512     else
1513     {
1514       frac0x=0;
1515       frac0=frac1;
1516     }
1517   }
1518 
1519   to->sign=(mask != 0);
1520   to->intg=intg0*DIG_PER_DEC1+intg0x;
1521   to->frac=frac0*DIG_PER_DEC1+frac0x;
1522 
1523   if (intg0x)
1524   {
1525     int i=dig2bytes[intg0x];
1526     dec1 x= 0;
1527     switch (i)
1528     {
1529       case 1: x=mi_sint1korr(from); break;
1530       case 2: x=mi_sint2korr(from); break;
1531       case 3: x=mi_sint3korr(from); break;
1532       case 4: x=mi_sint4korr(from); break;
1533       default: DBUG_ASSERT(0);
1534     }
1535     from+=i;
1536     *buf=x ^ mask;
1537     if (((ulonglong)*buf) >= (ulonglong) powers10[intg0x+1])
1538       goto err;
1539     if (buf > to->buf || *buf != 0)
1540       buf++;
1541     else
1542       to->intg-=intg0x;
1543   }
1544   for (stop=from+intg0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1545   {
1546     DBUG_ASSERT(sizeof(dec1) == 4);
1547     *buf=mi_sint4korr(from) ^ mask;
1548     if (((uint32)*buf) > DIG_MAX)
1549       goto err;
1550     if (buf > to->buf || *buf != 0)
1551       buf++;
1552     else
1553       to->intg-=DIG_PER_DEC1;
1554   }
1555   DBUG_ASSERT(to->intg >=0);
1556   for (stop=from+frac0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1557   {
1558     DBUG_ASSERT(sizeof(dec1) == 4);
1559     *buf=mi_sint4korr(from) ^ mask;
1560     if (((uint32)*buf) > DIG_MAX)
1561       goto err;
1562     buf++;
1563   }
1564   if (frac0x)
1565   {
1566     int i=dig2bytes[frac0x];
1567     dec1 x= 0;
1568     switch (i)
1569     {
1570       case 1: x=mi_sint1korr(from); break;
1571       case 2: x=mi_sint2korr(from); break;
1572       case 3: x=mi_sint3korr(from); break;
1573       case 4: x=mi_sint4korr(from); break;
1574       default: DBUG_ASSERT(0);
1575     }
1576     *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
1577     if (((uint32)*buf) > DIG_MAX)
1578       goto err;
1579     buf++;
1580   }
1581 
1582   /*
1583     No digits? We have read the number zero, of unspecified precision.
1584     Make it a proper zero, with non-zero precision.
1585   */
1586   if (to->intg == 0 && to->frac == 0)
1587     decimal_make_zero(to);
1588   return error;
1589 
1590 err:
1591   decimal_make_zero(to);
1592   return(E_DEC_BAD_NUM);
1593 }
1594 
1595 /*
1596   Returns the size of array to hold a decimal with given precision and scale
1597 
1598   RETURN VALUE
1599     size in dec1
1600     (multiply by sizeof(dec1) to get the size if bytes)
1601 */
1602 
decimal_size(int precision,int scale)1603 int decimal_size(int precision, int scale)
1604 {
1605   DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
1606   return ROUND_UP(precision-scale)+ROUND_UP(scale);
1607 }
1608 
1609 /*
1610   Returns the size of array to hold a binary representation of a decimal
1611 
1612   RETURN VALUE
1613     size in bytes
1614 */
1615 
decimal_bin_size(int precision,int scale)1616 int decimal_bin_size(int precision, int scale)
1617 {
1618   int intg=precision-scale,
1619       intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1620       intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1;
1621 
1622   DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
1623   DBUG_ASSERT(intg0x >= 0);
1624   DBUG_ASSERT(intg0x <= DIG_PER_DEC1);
1625   DBUG_ASSERT(frac0x >= 0);
1626   DBUG_ASSERT(frac0x <= DIG_PER_DEC1);
1627   return intg0*sizeof(dec1)+dig2bytes[intg0x]+
1628          frac0*sizeof(dec1)+dig2bytes[frac0x];
1629 }
1630 
1631 /*
1632   Rounds the decimal to "scale" digits
1633 
1634   SYNOPSIS
1635     decimal_round()
1636       from    - decimal to round,
1637       to      - result buffer. from==to is allowed
1638       scale   - to what position to round. can be negative!
1639       mode    - round to nearest even or truncate
1640 
1641   NOTES
1642     scale can be negative !
1643     one TRUNCATED error (line XXX below) isn't treated very logical :(
1644 
1645   RETURN VALUE
1646     E_DEC_OK/E_DEC_TRUNCATED
1647 */
1648 
1649 int
decimal_round(const decimal_t * from,decimal_t * to,int scale,decimal_round_mode mode)1650 decimal_round(const decimal_t *from, decimal_t *to, int scale,
1651               decimal_round_mode mode)
1652 {
1653   int frac0=scale>0 ? ROUND_UP(scale) : (scale + 1)/DIG_PER_DEC1,
1654     frac1=ROUND_UP(from->frac), round_digit= 0,
1655     intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len;
1656 
1657   dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
1658   int first_dig;
1659 
1660   sanity(to);
1661 
1662   switch (mode) {
1663   case HALF_UP:
1664   case HALF_EVEN:       round_digit=5; break;
1665   case CEILING:         round_digit= from->sign ? 10 : 0; break;
1666   case FLOOR:           round_digit= from->sign ? 0 : 10; break;
1667   case TRUNCATE:        round_digit=10; break;
1668   default: DBUG_ASSERT(0);
1669   }
1670 
1671   /*
1672     For my_decimal we always use len == DECIMAL_BUFF_LENGTH == 9
1673     For internal testing here (ifdef MAIN) we always use len == 100/4
1674    */
1675   DBUG_ASSERT(from->len == to->len);
1676 
1677   if (unlikely(frac0+intg0 > len))
1678   {
1679     frac0=len-intg0;
1680     scale=frac0*DIG_PER_DEC1;
1681     error=E_DEC_TRUNCATED;
1682   }
1683 
1684   if (scale+from->intg < 0)
1685   {
1686     decimal_make_zero(to);
1687     return E_DEC_OK;
1688   }
1689 
1690   if (to != from)
1691   {
1692     dec1 *p0= buf0 + intg0 + MY_MAX(frac1, frac0);
1693     dec1 *p1= buf1 + intg0 + MY_MAX(frac1, frac0);
1694 
1695     DBUG_ASSERT(p0 - buf0 <= len);
1696     DBUG_ASSERT(p1 - buf1 <= len);
1697 
1698     while (buf0 < p0)
1699       *(--p1) = *(--p0);
1700 
1701     buf0=to->buf;
1702     buf1=to->buf;
1703     to->sign=from->sign;
1704     to->intg= MY_MIN(intg0, len) * DIG_PER_DEC1;
1705   }
1706 
1707   if (frac0 > frac1)
1708   {
1709     buf1+=intg0+frac1;
1710     while (frac0-- > frac1)
1711       *buf1++=0;
1712     goto done;
1713   }
1714 
1715   if (scale >= from->frac)
1716     goto done; /* nothing to do */
1717 
1718   buf0+=intg0+frac0-1;
1719   buf1+=intg0+frac0-1;
1720   if (scale == frac0*DIG_PER_DEC1)
1721   {
1722     int do_inc= FALSE;
1723     DBUG_ASSERT(frac0+intg0 >= 0);
1724     switch (round_digit) {
1725     case 0:
1726     {
1727       dec1 *p0= buf0 + (frac1-frac0);
1728       for (; p0 > buf0; p0--)
1729       {
1730         if (*p0)
1731         {
1732           do_inc= TRUE;
1733           break;
1734         }
1735       }
1736       break;
1737     }
1738     case 5:
1739     {
1740       x= buf0[1]/DIG_MASK;
1741       do_inc= (x>5) || ((x == 5) &&
1742                         (mode == HALF_UP || (frac0+intg0 > 0 && *buf0 & 1)));
1743       break;
1744     }
1745     default:
1746       break;
1747     }
1748     if (do_inc)
1749     {
1750       if (frac0+intg0>0)
1751         (*buf1)++;
1752       else
1753         *(++buf1)=DIG_BASE;
1754     }
1755     else if (frac0+intg0==0)
1756     {
1757       decimal_make_zero(to);
1758       return E_DEC_OK;
1759     }
1760   }
1761   else
1762   {
1763     /* TODO - fix this code as it won't work for CEILING mode */
1764     int pos=frac0*DIG_PER_DEC1-scale-1;
1765     DBUG_ASSERT(frac0+intg0 > 0);
1766     x=*buf1 / powers10[pos];
1767     y=x % 10;
1768     if (y > round_digit ||
1769         (round_digit == 5 && y == 5 && (mode == HALF_UP || (x/10) & 1)))
1770       x+=10;
1771     *buf1=powers10[pos]*(x-y);
1772   }
1773   /*
1774     In case we're rounding e.g. 1.5e9 to 2.0e9, the decimal_digit_t's inside
1775     the buffer are as follows.
1776 
1777     Before <1, 5e8>
1778     After  <2, 5e8>
1779 
1780     Hence we need to set the 2nd field to 0.
1781     The same holds if we round 1.5e-9 to 2e-9.
1782    */
1783   if (frac0 < frac1)
1784   {
1785     dec1 *buf= to->buf + ((scale == 0 && intg0 == 0) ? 1 : intg0 + frac0);
1786     dec1 *end= to->buf + len;
1787 
1788     while (buf < end)
1789       *buf++=0;
1790   }
1791   if (*buf1 >= DIG_BASE)
1792   {
1793     carry=1;
1794     *buf1-=DIG_BASE;
1795     while (carry && --buf1 >= to->buf)
1796       ADD(*buf1, *buf1, 0, carry);
1797     if (unlikely(carry))
1798     {
1799       /* shifting the number to create space for new digit */
1800       if (frac0+intg0 >= len)
1801       {
1802         frac0--;
1803         scale=frac0*DIG_PER_DEC1;
1804         error=E_DEC_TRUNCATED; /* XXX */
1805       }
1806       for (buf1=to->buf + intg0 + MY_MAX(frac0, 0); buf1 > to->buf; buf1--)
1807       {
1808         /* Avoid out-of-bounds write. */
1809         if (buf1 < to->buf + len)
1810           buf1[0]=buf1[-1];
1811         else
1812           error= E_DEC_OVERFLOW;
1813       }
1814       *buf1=1;
1815       /* We cannot have more than 9 * 9 = 81 digits. */
1816       if (to->intg < len * DIG_PER_DEC1)
1817         to->intg++;
1818       else
1819         error= E_DEC_OVERFLOW;
1820     }
1821   }
1822   else
1823   {
1824     for (;;)
1825     {
1826       if (likely(*buf1))
1827         break;
1828       if (buf1-- == to->buf)
1829       {
1830         /* making 'zero' with the proper scale */
1831         dec1 *p0= to->buf + frac0 + 1;
1832         to->intg=1;
1833         to->frac= MY_MAX(scale, 0);
1834         to->sign= 0;
1835         for (buf1= to->buf; buf1<p0; buf1++)
1836           *buf1= 0;
1837         return E_DEC_OK;
1838       }
1839     }
1840   }
1841 
1842   /* Here we  check 999.9 -> 1000 case when we need to increase intg */
1843   first_dig= to->intg % DIG_PER_DEC1;
1844   if (first_dig && (*buf1 >= powers10[first_dig]))
1845     to->intg++;
1846 
1847   if (scale<0)
1848     scale=0;
1849 
1850 done:
1851   DBUG_ASSERT(to->intg <= (len * DIG_PER_DEC1));
1852   to->frac=scale;
1853   return error;
1854 }
1855 
1856 /*
1857   Returns the size of the result of the operation
1858 
1859   SYNOPSIS
1860     decimal_result_size()
1861       from1   - operand of the unary operation or first operand of the
1862                 binary operation
1863       from2   - second operand of the binary operation
1864       op      - operation. one char '+', '-', '*', '/' are allowed
1865                 others may be added later
1866       param   - extra param to the operation. unused for '+', '-', '*'
1867                 scale increment for '/'
1868 
1869   NOTE
1870     returned valued may be larger than the actual buffer requred
1871     in the operation, as decimal_result_size, by design, operates on
1872     precision/scale values only and not on the actual decimal number
1873 
1874   RETURN VALUE
1875     size of to->buf array in dec1 elements. to get size in bytes
1876     multiply by sizeof(dec1)
1877 */
1878 
decimal_result_size(decimal_t * from1,decimal_t * from2,char op,int param)1879 int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, int param)
1880 {
1881   switch (op) {
1882   case '-':
1883     return ROUND_UP(MY_MAX(from1->intg, from2->intg)) +
1884            ROUND_UP(MY_MAX(from1->frac, from2->frac));
1885   case '+':
1886     return ROUND_UP(MY_MAX(from1->intg, from2->intg)+1) +
1887            ROUND_UP(MY_MAX(from1->frac, from2->frac));
1888   case '*':
1889     return ROUND_UP(from1->intg+from2->intg)+
1890            ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
1891   case '/':
1892     return ROUND_UP(from1->intg+from2->intg+1+from1->frac+from2->frac+param);
1893   default: DBUG_ASSERT(0);
1894   }
1895   return -1; /* shut up the warning */
1896 }
1897 
do_add(const decimal_t * from1,const decimal_t * from2,decimal_t * to)1898 static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1899 {
1900   int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1901       frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1902       frac0= MY_MAX(frac1, frac2), intg0= MY_MAX(intg1, intg2), error;
1903   dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
1904 
1905   sanity(to);
1906 
1907   /* is there a need for extra word because of carry ? */
1908   x=intg1 > intg2 ? from1->buf[0] :
1909     intg2 > intg1 ? from2->buf[0] :
1910     from1->buf[0] + from2->buf[0] ;
1911   if (unlikely(x > DIG_MAX-1)) /* yes, there is */
1912   {
1913     intg0++;
1914     to->buf[0]=0; /* safety */
1915   }
1916 
1917   FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
1918   if (unlikely(error == E_DEC_OVERFLOW))
1919   {
1920     max_decimal(to->len * DIG_PER_DEC1, 0, to);
1921     return error;
1922   }
1923 
1924   buf0=to->buf+intg0+frac0;
1925 
1926   to->sign=from1->sign;
1927   to->frac= MY_MAX(from1->frac, from2->frac);
1928   to->intg=intg0*DIG_PER_DEC1;
1929   if (unlikely(error))
1930   {
1931     set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
1932     set_if_smaller(frac1, frac0);
1933     set_if_smaller(frac2, frac0);
1934     set_if_smaller(intg1, intg0);
1935     set_if_smaller(intg2, intg0);
1936   }
1937 
1938   /* part 1 - max(frac) ... min (frac) */
1939   if (frac1 > frac2)
1940   {
1941     buf1=from1->buf+intg1+frac1;
1942     stop=from1->buf+intg1+frac2;
1943     buf2=from2->buf+intg2+frac2;
1944     stop2=from1->buf+(intg1 > intg2 ? intg1-intg2 : 0);
1945   }
1946   else
1947   {
1948     buf1=from2->buf+intg2+frac2;
1949     stop=from2->buf+intg2+frac1;
1950     buf2=from1->buf+intg1+frac1;
1951     stop2=from2->buf+(intg2 > intg1 ? intg2-intg1 : 0);
1952   }
1953   while (buf1 > stop)
1954     *--buf0=*--buf1;
1955 
1956   /* part 2 - min(frac) ... min(intg) */
1957   carry=0;
1958   while (buf1 > stop2)
1959   {
1960     ADD(*--buf0, *--buf1, *--buf2, carry);
1961   }
1962 
1963   /* part 3 - min(intg) ... max(intg) */
1964   buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
1965                         ((stop=from2->buf)+intg2-intg1) ;
1966   while (buf1 > stop)
1967   {
1968     ADD(*--buf0, *--buf1, 0, carry);
1969   }
1970 
1971   if (unlikely(carry))
1972     *--buf0=1;
1973   DBUG_ASSERT(buf0 == to->buf || buf0 == to->buf+1);
1974 
1975   return error;
1976 }
1977 
1978 /* to=from1-from2.
1979    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)1980 static int do_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1981 {
1982   int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1983       frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
1984   int frac0= MY_MAX(frac1, frac2), error;
1985   dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
1986 
1987   /* let carry:=1 if from2 > from1 */
1988   start1=buf1=from1->buf; stop1=buf1+intg1;
1989   start2=buf2=from2->buf; stop2=buf2+intg2;
1990   if (unlikely(*buf1 == 0))
1991   {
1992     while (buf1 < stop1 && *buf1 == 0)
1993       buf1++;
1994     start1=buf1;
1995     intg1= (int) (stop1-buf1);
1996   }
1997   if (unlikely(*buf2 == 0))
1998   {
1999     while (buf2 < stop2 && *buf2 == 0)
2000       buf2++;
2001     start2=buf2;
2002     intg2= (int) (stop2-buf2);
2003   }
2004   if (intg2 > intg1)
2005     carry=1;
2006   else if (intg2 == intg1)
2007   {
2008     dec1 *end1= stop1 + (frac1 - 1);
2009     dec1 *end2= stop2 + (frac2 - 1);
2010     while (unlikely((buf1 <= end1) && (*end1 == 0)))
2011       end1--;
2012     while (unlikely((buf2 <= end2) && (*end2 == 0)))
2013       end2--;
2014     frac1= (int) (end1 - stop1) + 1;
2015     frac2= (int) (end2 - stop2) + 1;
2016     while (buf1 <=end1 && buf2 <= end2 && *buf1 == *buf2)
2017       buf1++, buf2++;
2018     if (buf1 <= end1)
2019     {
2020       if (buf2 <= end2)
2021         carry= *buf2 > *buf1;
2022       else
2023         carry= 0;
2024     }
2025     else
2026     {
2027       if (buf2 <= end2)
2028         carry=1;
2029       else /* short-circuit everything: from1 == from2 */
2030       {
2031         if (to == 0) /* decimal_cmp() */
2032           return 0;
2033         decimal_make_zero(to);
2034         return E_DEC_OK;
2035       }
2036     }
2037   }
2038 
2039   if (to == 0) /* decimal_cmp() */
2040     return carry == from1->sign ? 1 : -1;
2041 
2042   sanity(to);
2043 
2044   to->sign=from1->sign;
2045 
2046   /* ensure that always from1 > from2 (and intg1 >= intg2) */
2047   if (carry)
2048   {
2049     swap_variables(const decimal_t *, from1, from2);
2050     swap_variables(dec1 *,start1, start2);
2051     swap_variables(int,intg1,intg2);
2052     swap_variables(int,frac1,frac2);
2053     to->sign= 1 - to->sign;
2054   }
2055 
2056   FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
2057   buf0=to->buf+intg1+frac0;
2058 
2059   to->frac= MY_MAX(from1->frac, from2->frac);
2060   to->intg=intg1*DIG_PER_DEC1;
2061   if (unlikely(error))
2062   {
2063     set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
2064     set_if_smaller(frac1, frac0);
2065     set_if_smaller(frac2, frac0);
2066     set_if_smaller(intg2, intg1);
2067   }
2068   carry=0;
2069 
2070   /* part 1 - max(frac) ... min (frac) */
2071   if (frac1 > frac2)
2072   {
2073     buf1=start1+intg1+frac1;
2074     stop1=start1+intg1+frac2;
2075     buf2=start2+intg2+frac2;
2076     while (frac0-- > frac1)
2077       *--buf0=0;
2078     while (buf1 > stop1)
2079       *--buf0=*--buf1;
2080   }
2081   else
2082   {
2083     buf1=start1+intg1+frac1;
2084     buf2=start2+intg2+frac2;
2085     stop2=start2+intg2+frac1;
2086     while (frac0-- > frac2)
2087       *--buf0=0;
2088     while (buf2 > stop2)
2089     {
2090       SUB(*--buf0, 0, *--buf2, carry);
2091     }
2092   }
2093 
2094   /* part 2 - min(frac) ... intg2 */
2095   while (buf2 > start2)
2096   {
2097     SUB(*--buf0, *--buf1, *--buf2, carry);
2098   }
2099 
2100   /* part 3 - intg2 ... intg1 */
2101   while (carry && buf1 > start1)
2102   {
2103     SUB(*--buf0, *--buf1, 0, carry);
2104   }
2105 
2106   while (buf1 > start1)
2107     *--buf0=*--buf1;
2108 
2109   while (buf0 > to->buf)
2110     *--buf0=0;
2111 
2112   return error;
2113 }
2114 
decimal_intg(const decimal_t * from)2115 int decimal_intg(const decimal_t *from)
2116 {
2117   int res;
2118   remove_leading_zeroes(from, &res);
2119   return res;
2120 }
2121 
decimal_add(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2122 int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2123 {
2124   if (likely(from1->sign == from2->sign))
2125     return do_add(from1, from2, to);
2126   return do_sub(from1, from2, to);
2127 }
2128 
decimal_sub(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2129 int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2130 {
2131   if (likely(from1->sign == from2->sign))
2132     return do_sub(from1, from2, to);
2133   return do_add(from1, from2, to);
2134 }
2135 
decimal_cmp(const decimal_t * from1,const decimal_t * from2)2136 int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
2137 {
2138   if (likely(from1->sign == from2->sign))
2139     return do_sub(from1, from2, 0);
2140 
2141   // Reject negative zero, cfr. internal_str2dec()
2142   DBUG_ASSERT(!(decimal_is_zero(from1) && from1->sign));
2143   DBUG_ASSERT(!(decimal_is_zero(from2) && from2->sign));
2144 
2145   return from1->sign > from2->sign ? -1 : 1;
2146 }
2147 
decimal_is_zero(const decimal_t * from)2148 int decimal_is_zero(const decimal_t *from)
2149 {
2150   dec1 *buf1=from->buf,
2151        *end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
2152   while (buf1 < end)
2153     if (*buf1++)
2154       return 0;
2155   return 1;
2156 }
2157 
2158 /*
2159   multiply two decimals
2160 
2161   SYNOPSIS
2162     decimal_mul()
2163       from1, from2 - factors
2164       to      - product
2165 
2166   RETURN VALUE
2167     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW;
2168 
2169   NOTES
2170     in this implementation, with sizeof(dec1)=4 we have DIG_PER_DEC1=9,
2171     and 63-digit number will take only 7 dec1 words (basically a 7-digit
2172     "base 999999999" number).  Thus there's no need in fast multiplication
2173     algorithms, 7-digit numbers can be multiplied with a naive O(n*n)
2174     method.
2175 
2176     XXX if this library is to be used with huge numbers of thousands of
2177     digits, fast multiplication must be implemented.
2178 */
decimal_mul(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2179 int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2180 {
2181   int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
2182       frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
2183       intg0=ROUND_UP(from1->intg+from2->intg),
2184       frac0=frac1+frac2, error, iii, jjj, d_to_move;
2185   dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
2186        *start2, *stop2, *stop1, *start0, carry;
2187 
2188   sanity(to);
2189 
2190   iii= intg0;                                       /* save 'ideal' values */
2191   jjj= frac0;
2192   FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);  /* bound size */
2193   to->sign= from1->sign != from2->sign;
2194   to->frac= from1->frac + from2->frac;              /* store size in digits */
2195   set_if_smaller(to->frac, NOT_FIXED_DEC);
2196   to->intg=intg0*DIG_PER_DEC1;
2197 
2198   if (unlikely(error))
2199   {
2200     set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
2201     set_if_smaller(to->intg, intg0*DIG_PER_DEC1);
2202     if (unlikely(iii > intg0))                     /* bounded integer-part */
2203     {
2204       iii-=intg0;
2205       jjj= iii >> 1;
2206       intg1-= jjj;
2207       intg2-=iii-jjj;
2208       frac1=frac2=0; /* frac0 is already 0 here */
2209     }
2210     else                                         /* bounded fract part */
2211     {
2212       jjj-=frac0;
2213       iii=jjj >> 1;
2214       if (frac1 <= frac2)
2215       {
2216         frac1-= iii;
2217         frac2-=jjj-iii;
2218       }
2219       else
2220       {
2221         frac2-= iii;
2222         frac1-=jjj-iii;
2223       }
2224     }
2225   }
2226   start0=to->buf+intg0+frac0-1;
2227   start2=buf2+frac2-1;
2228   stop1=buf1-intg1;
2229   stop2=buf2-intg2;
2230 
2231   memset(to->buf, 0, (intg0+frac0)*sizeof(dec1));
2232 
2233   for (buf1+=frac1-1; buf1 >= stop1; buf1--, start0--)
2234   {
2235     carry=0;
2236     for (buf0=start0, buf2=start2; buf2 >= stop2; buf2--, buf0--)
2237     {
2238       dec1 hi, lo;
2239       dec2 p= ((dec2)*buf1) * ((dec2)*buf2);
2240       hi=(dec1)(p/DIG_BASE);
2241       lo=(dec1)(p-((dec2)hi)*DIG_BASE);
2242       ADD2(*buf0, *buf0, lo, carry);
2243       carry+=hi;
2244     }
2245     if (carry)
2246     {
2247       if (buf0 < to->buf)
2248         return E_DEC_OVERFLOW;
2249       ADD2(*buf0, *buf0, 0, carry);
2250     }
2251     for (buf0--; carry; buf0--)
2252     {
2253       if (buf0 < to->buf)
2254         return E_DEC_OVERFLOW;
2255       ADD(*buf0, *buf0, 0, carry);
2256     }
2257   }
2258 
2259   /* Now we have to check for -0.000 case */
2260   if (to->sign)
2261   {
2262     dec1 *buf= to->buf;
2263     dec1 *end= to->buf + intg0 + frac0;
2264     DBUG_ASSERT(buf != end);
2265     for (;;)
2266     {
2267       if (*buf)
2268         break;
2269       if (++buf == end)
2270       {
2271         /* We got decimal zero */
2272         decimal_make_zero(to);
2273         break;
2274       }
2275     }
2276   }
2277   buf1= to->buf;
2278   d_to_move= intg0 + ROUND_UP(to->frac);
2279   while (!*buf1 && (to->intg > DIG_PER_DEC1))
2280   {
2281     buf1++;
2282     to->intg-= DIG_PER_DEC1;
2283     d_to_move--;
2284   }
2285   if (to->buf < buf1)
2286   {
2287     dec1 *cur_d= to->buf;
2288     for (; d_to_move--; cur_d++, buf1++)
2289       *cur_d= *buf1;
2290   }
2291   return error;
2292 }
2293 
2294 /*
2295   naive division algorithm (Knuth's Algorithm D in 4.3.1) -
2296   it's ok for short numbers
2297   also we're using alloca() to allocate a temporary buffer
2298 
2299   XXX if this library is to be used with huge numbers of thousands of
2300   digits, fast division must be implemented and alloca should be
2301   changed to malloc (or at least fallback to malloc if alloca() fails)
2302   but then, decimal_mul() should be rewritten too :(
2303 */
do_div_mod(const decimal_t * from1,const decimal_t * from2,decimal_t * to,decimal_t * mod,int scale_incr)2304 static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
2305                       decimal_t *to, decimal_t *mod, int scale_incr)
2306 {
2307 
2308   /*
2309     frac* - number of digits in fractional part of the number
2310     prec* - precision of the number
2311     intg* - number of digits in the integer part
2312     buf* - buffer having the actual number
2313     All variables ending with 0 - like frac0, intg0 etc are
2314     for the final result. Similarly frac1, intg1 etc are for
2315     the first number and frac2, intg2 etc are for the second number
2316    */
2317   int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2318       frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2319       error= 0, i, intg0, frac0, len1, len2,
2320       dintg, /* Holds the estimate of number of integer digits in final result */
2321       div_mod=(!mod) /*true if this is division */;
2322   dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *start1, *stop1,
2323        *start2, *stop2, *stop0 ,norm2, carry, dcarry, *tmp1;
2324   dec2 norm_factor, x, guess, y;
2325 
2326   if (mod)
2327     to=mod;
2328 
2329   sanity(to);
2330 
2331   /*
2332     removing all the leading zeroes in the second number. Leading zeroes are
2333     added later to the result.
2334    */
2335   i= ((prec2 - 1) % DIG_PER_DEC1) + 1;
2336   while (prec2 > 0 && *buf2 == 0)
2337   {
2338     prec2-= i;
2339     i= DIG_PER_DEC1;
2340     buf2++;
2341   }
2342   if (prec2 <= 0) /* short-circuit everything: from2 == 0 */
2343     return E_DEC_DIV_ZERO;
2344 
2345   /*
2346     Remove the remanining zeroes . For ex: for 0.000000000001
2347     the above while loop removes 9 zeroes and the result will have 0.0001
2348     these remaining zeroes are removed here
2349    */
2350   prec2-= count_leading_zeroes((prec2 - 1) % DIG_PER_DEC1, *buf2);
2351   DBUG_ASSERT(prec2 > 0);
2352 
2353   /*
2354    Do the same for the first number. Remove the leading zeroes.
2355    Check if the number is actually 0. Then remove the remaining zeroes.
2356    */
2357 
2358   i=((prec1-1) % DIG_PER_DEC1)+1;
2359   while (prec1 > 0 && *buf1 == 0)
2360   {
2361     prec1-=i;
2362     i=DIG_PER_DEC1;
2363     buf1++;
2364   }
2365   if (prec1 <= 0)
2366   { /* short-circuit everything: from1 == 0 */
2367     decimal_make_zero(to);
2368     return E_DEC_OK;
2369   }
2370   prec1-= count_leading_zeroes((prec1-1) % DIG_PER_DEC1, *buf1);
2371   DBUG_ASSERT(prec1 > 0);
2372 
2373   /* let's fix scale_incr, taking into account frac1,frac2 increase */
2374   if ((scale_incr-= frac1 - from1->frac + frac2 - from2->frac) < 0)
2375     scale_incr=0;
2376 
2377   /* Calculate the integer digits in final result */
2378   dintg=(prec1-frac1)-(prec2-frac2)+(*buf1 >= *buf2);
2379   if (dintg < 0)
2380   {
2381     dintg/=DIG_PER_DEC1;
2382     intg0=0;
2383   }
2384   else
2385     intg0=ROUND_UP(dintg);
2386   if (mod)
2387   {
2388     /* we're calculating N1 % N2.
2389        The result will have
2390          frac=max(frac1, frac2), as for subtraction
2391          intg=intg2
2392     */
2393     to->sign=from1->sign;
2394     to->frac= MY_MAX(from1->frac, from2->frac);
2395     frac0=0;
2396   }
2397   else
2398   {
2399     /*
2400       we're calculating N1/N2. N1 is in the buf1, has prec1 digits
2401       N2 is in the buf2, has prec2 digits. Scales are frac1 and
2402       frac2 accordingly.
2403       Thus, the result will have
2404          frac = ROUND_UP(frac1+frac2+scale_incr)
2405       and
2406          intg = (prec1-frac1) - (prec2-frac2) + 1
2407          prec = intg+frac
2408     */
2409     frac0=ROUND_UP(frac1+frac2+scale_incr);
2410     FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
2411     to->sign=from1->sign != from2->sign;
2412     to->intg=intg0*DIG_PER_DEC1;
2413     to->frac=frac0*DIG_PER_DEC1;
2414   }
2415   buf0=to->buf;
2416   stop0=buf0+intg0+frac0;
2417   if (likely(div_mod))
2418     while (dintg++ < 0 && buf0 < &to->buf[to->len])
2419     {
2420       *buf0++=0;
2421     }
2422 
2423   len1=(i=ROUND_UP(prec1))+ROUND_UP(2*frac2+scale_incr+1) + 1;
2424   set_if_bigger(len1, 3);
2425   if (!(tmp1=(dec1 *)my_alloca(len1*sizeof(dec1))))
2426     return E_DEC_OOM;
2427   memcpy(tmp1, buf1, i*sizeof(dec1));
2428   memset(tmp1+i, 0, (len1-i)*sizeof(dec1));
2429 
2430   start1=tmp1;
2431   stop1=start1+len1;
2432   start2=buf2;
2433   stop2=buf2+ROUND_UP(prec2)-1;
2434 
2435   /* removing end zeroes */
2436   while (*stop2 == 0 && stop2 >= start2)
2437     stop2--;
2438   len2= (int) (stop2++ - start2);
2439 
2440   /*
2441     calculating norm2 (normalized *start2) - we need *start2 to be large
2442     (at least > DIG_BASE/2), but unlike Knuth's Alg. D we don't want to
2443     normalize input numbers (as we don't make a copy of the divisor).
2444     Thus we normalize first dec1 of buf2 only, and we'll normalize *start1
2445     on the fly for the purpose of guesstimation only.
2446     It's also faster, as we're saving on normalization of buf2
2447   */
2448   norm_factor=DIG_BASE/(*start2+1);
2449   norm2=(dec1)(norm_factor*start2[0]);
2450   if (likely(len2>0))
2451     norm2+=(dec1)(norm_factor*start2[1]/DIG_BASE);
2452 
2453   if (*start1 < *start2)
2454     dcarry=*start1++;
2455   else
2456     dcarry=0;
2457 
2458   /* main loop */
2459   for (; buf0 < stop0; buf0++)
2460   {
2461     /* short-circuit, if possible */
2462     if (unlikely(dcarry == 0 && *start1 < *start2))
2463       guess=0;
2464     else
2465     {
2466       /* D3: make a guess */
2467       x=start1[0]+((dec2)dcarry)*DIG_BASE;
2468       y=start1[1];
2469       guess=(norm_factor*x+norm_factor*y/DIG_BASE)/norm2;
2470       if (unlikely(guess >= DIG_BASE))
2471         guess=DIG_BASE-1;
2472       if (likely(len2>0))
2473       {
2474         /* hmm, this is a suspicious trick - I removed normalization here */
2475         if (start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y)
2476           guess--;
2477         if (unlikely(start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y))
2478           guess--;
2479         DBUG_ASSERT(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y);
2480       }
2481 
2482       /* D4: multiply and subtract */
2483       buf2=stop2;
2484       buf1=start1+len2;
2485       DBUG_ASSERT(buf1 < stop1);
2486       for (carry=0; buf2 > start2; buf1--)
2487       {
2488         dec1 hi, lo;
2489         x=guess * (*--buf2);
2490         hi=(dec1)(x/DIG_BASE);
2491         lo=(dec1)(x-((dec2)hi)*DIG_BASE);
2492         SUB2(*buf1, *buf1, lo, carry);
2493         carry+=hi;
2494       }
2495       carry= dcarry < carry;
2496 
2497       /* D5: check the remainder */
2498       if (unlikely(carry))
2499       {
2500         /* D6: correct the guess */
2501         guess--;
2502         buf2=stop2;
2503         buf1=start1+len2;
2504         for (carry=0; buf2 > start2; buf1--)
2505         {
2506           ADD(*buf1, *buf1, *--buf2, carry);
2507         }
2508       }
2509     }
2510     if (likely(div_mod))
2511     {
2512       DBUG_ASSERT(buf0 < to->buf + to->len);
2513       *buf0=(dec1)guess;
2514     }
2515     dcarry= *start1;
2516     start1++;
2517   }
2518   if (mod)
2519   {
2520     /*
2521       now the result is in tmp1, it has
2522       intg=prec1-frac1  if there were no leading zeroes.
2523                         If leading zeroes were present, they have been removed
2524                         earlier. We need to now add them back to the result.
2525       frac=max(frac1, frac2)=to->frac
2526      */
2527     if (dcarry)
2528       *--start1=dcarry;
2529     buf0=to->buf;
2530     /* Calculate the final result's integer digits */
2531     dintg= (prec1 - frac1) - ((start1 - tmp1) * DIG_PER_DEC1);
2532     if (dintg < 0)
2533     {
2534       /* If leading zeroes in the fractional part were earlier stripped */
2535       intg0= dintg / DIG_PER_DEC1;
2536     }
2537     else
2538       intg0= ROUND_UP(dintg);
2539     frac0=ROUND_UP(to->frac);
2540     error=E_DEC_OK;
2541     if (unlikely(frac0==0 && intg0==0))
2542     {
2543       decimal_make_zero(to);
2544       goto done;
2545     }
2546     if (intg0<=0)
2547     {
2548       /* Add back the leading zeroes that were earlier stripped */
2549       if (unlikely(-intg0 >= to->len))
2550       {
2551         decimal_make_zero(to);
2552         error=E_DEC_TRUNCATED;
2553         goto done;
2554       }
2555       stop1= start1 + frac0 + intg0;
2556       frac0+=intg0;
2557       to->intg=0;
2558       while (intg0++ < 0)
2559         *buf0++=0;
2560     }
2561     else
2562     {
2563       if (unlikely(intg0 > to->len))
2564       {
2565         frac0=0;
2566         intg0=to->len;
2567         error=E_DEC_OVERFLOW;
2568         goto done;
2569       }
2570       DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
2571       stop1=start1+frac0+intg0;
2572       to->intg= MY_MIN(intg0 * DIG_PER_DEC1, from2->intg);
2573     }
2574     if (unlikely(intg0+frac0 > to->len))
2575     {
2576       stop1-=frac0+intg0-to->len;
2577       frac0=to->len-intg0;
2578       to->frac=frac0*DIG_PER_DEC1;
2579         error=E_DEC_TRUNCATED;
2580     }
2581     DBUG_ASSERT(buf0 + (stop1 - start1) <= to->buf + to->len);
2582     while (start1 < stop1)
2583         *buf0++=*start1++;
2584   }
2585 done:
2586   tmp1= remove_leading_zeroes(to, &to->intg);
2587   if(to->buf != tmp1)
2588     memmove(to->buf, tmp1,
2589             (ROUND_UP(to->intg) + ROUND_UP(to->frac)) * sizeof(dec1));
2590   return error;
2591 }
2592 
2593 /*
2594   division of two decimals
2595 
2596   SYNOPSIS
2597     decimal_div()
2598       from1   - dividend
2599       from2   - divisor
2600       to      - quotient
2601 
2602   RETURN VALUE
2603     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2604 
2605   NOTES
2606     see do_div_mod()
2607 */
2608 
2609 int
decimal_div(const decimal_t * from1,const decimal_t * from2,decimal_t * to,int scale_incr)2610 decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to,
2611             int scale_incr)
2612 {
2613   return do_div_mod(from1, from2, to, 0, scale_incr);
2614 }
2615 
2616 /*
2617   modulus
2618 
2619   SYNOPSIS
2620     decimal_mod()
2621       from1   - dividend
2622       from2   - divisor
2623       to      - modulus
2624 
2625   RETURN VALUE
2626     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2627 
2628   NOTES
2629     see do_div_mod()
2630 
2631   DESCRIPTION
2632     the modulus R in    R = M mod N
2633 
2634    is defined as
2635 
2636      0 <= |R| < |M|
2637      sign R == sign M
2638      R = M - k*N, where k is integer
2639 
2640    thus, there's no requirement for M or N to be integers
2641 */
2642 
decimal_mod(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2643 int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2644 {
2645   return do_div_mod(from1, from2, 0, to, 0);
2646 }
2647 
2648 #ifdef MAIN
2649 /*
2650   The main() program has been converted into a unit test.
2651  */
2652 #endif
2653