1 /* Copyright (c) 2004, 2015, 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 #ifdef HAVE_purify
152 #define sanity(d) DBUG_ASSERT((d)->len > 0)
153 #else
154 #define sanity(d) DBUG_ASSERT((d)->len >0 && ((d)->buf[0] | \
155                               (d)->buf[(d)->len-1] | 1))
156 #endif
157 
158 #define FIX_INTG_FRAC_ERROR(len, intg1, frac1, error)                   \
159         do                                                              \
160         {                                                               \
161           if (unlikely(intg1+frac1 > (len)))                            \
162           {                                                             \
163             if (unlikely(intg1 > (len)))                                \
164             {                                                           \
165               intg1=(len);                                              \
166               frac1=0;                                                  \
167               error=E_DEC_OVERFLOW;                                     \
168             }                                                           \
169             else                                                        \
170             {                                                           \
171               frac1=(len)-intg1;                                        \
172               error=E_DEC_TRUNCATED;                                    \
173             }                                                           \
174           }                                                             \
175           else                                                          \
176             error=E_DEC_OK;                                             \
177         } while(0)
178 
179 #define ADD(to, from1, from2, carry)  /* assume carry <= 1 */           \
180         do                                                              \
181         {                                                               \
182           dec1 a=(from1)+(from2)+(carry);                               \
183           DBUG_ASSERT((carry) <= 1);                                    \
184           if (((carry)= a >= DIG_BASE)) /* no division here! */         \
185             a-=DIG_BASE;                                                \
186           (to)=a;                                                       \
187         } while(0)
188 
189 #define ADD2(to, from1, from2, carry)                                   \
190         do                                                              \
191         {                                                               \
192           dec2 a=((dec2)(from1))+(from2)+(carry);                       \
193           if (((carry)= a >= DIG_BASE))                                 \
194             a-=DIG_BASE;                                                \
195           if (unlikely(a >= DIG_BASE))                                  \
196           {                                                             \
197             a-=DIG_BASE;                                                \
198             carry++;                                                    \
199           }                                                             \
200           (to)=(dec1) a;                                                \
201         } while(0)
202 
203 #define SUB(to, from1, from2, carry) /* to=from1-from2 */               \
204         do                                                              \
205         {                                                               \
206           dec1 a=(from1)-(from2)-(carry);                               \
207           if (((carry)= a < 0))                                         \
208             a+=DIG_BASE;                                                \
209           (to)=a;                                                       \
210         } while(0)
211 
212 #define SUB2(to, from1, from2, carry) /* to=from1-from2 */              \
213         do                                                              \
214         {                                                               \
215           dec1 a=(from1)-(from2)-(carry);                               \
216           if (((carry)= a < 0))                                         \
217             a+=DIG_BASE;                                                \
218           if (unlikely(a < 0))                                          \
219           {                                                             \
220             a+=DIG_BASE;                                                \
221             carry++;                                                    \
222           }                                                             \
223           (to)=a;                                                       \
224         } while(0)
225 
226 
227 /*
228   This is a direct loop unrolling of code that used to look like this:
229   for (; *buf_beg < powers10[i--]; start++) ;
230 
231   @param   i    start index
232   @param   val  value to compare against list of powers of 10
233 
234   @retval  Number of leading zeroes that can be removed from fraction.
235 
236   @note Why unroll? To get rid of lots of compiler warnings [-Warray-bounds]
237         Nice bonus: unrolled code is significantly faster.
238  */
count_leading_zeroes(int i,dec1 val)239 static inline int count_leading_zeroes(int i, dec1 val)
240 {
241   int ret= 0;
242   switch (i)
243   {
244   /* @note Intentional fallthrough in all case labels */
245   case 9: if (val >= 1000000000) break; ++ret; // fallthrough
246   case 8: if (val >= 100000000) break; ++ret; // fallthrough
247   case 7: if (val >= 10000000) break; ++ret; // fallthrough
248   case 6: if (val >= 1000000) break; ++ret; // fallthrough
249   case 5: if (val >= 100000) break; ++ret; // fallthrough
250   case 4: if (val >= 10000) break; ++ret; // fallthrough
251   case 3: if (val >= 1000) break; ++ret; // fallthrough
252   case 2: if (val >= 100) break; ++ret; // fallthrough
253   case 1: if (val >= 10) break; ++ret; // fallthrough
254   case 0: if (val >= 1) break; ++ret; // fallthrough
255   default: { DBUG_ASSERT(FALSE); } // fallthrough
256   }
257   return ret;
258 }
259 
260 /*
261   This is a direct loop unrolling of code that used to look like this:
262   for (; *buf_end % powers10[i++] == 0; stop--) ;
263 
264   @param   i    start index
265   @param   val  value to compare against list of powers of 10
266 
267   @retval  Number of trailing zeroes that can be removed from fraction.
268 
269   @note Why unroll? To get rid of lots of compiler warnings [-Warray-bounds]
270         Nice bonus: unrolled code is significantly faster.
271  */
count_trailing_zeroes(int i,dec1 val)272 static inline int count_trailing_zeroes(int i, dec1 val)
273 {
274   int ret= 0;
275   switch(i)
276   {
277   /* @note Intentional fallthrough in all case labels */
278   case 0: if ((val % 1) != 0) break; ++ret; // fallthrough
279   case 1: if ((val % 10) != 0) break; ++ret; // fallthrough
280   case 2: if ((val % 100) != 0) break; ++ret; // fallthrough
281   case 3: if ((val % 1000) != 0) break; ++ret; // fallthrough
282   case 4: if ((val % 10000) != 0) break; ++ret; // fallthrough
283   case 5: if ((val % 100000) != 0) break; ++ret; // fallthrough
284   case 6: if ((val % 1000000) != 0) break; ++ret; // fallthrough
285   case 7: if ((val % 10000000) != 0) break; ++ret; // fallthrough
286   case 8: if ((val % 100000000) != 0) break; ++ret; // fallthrough
287   case 9: if ((val % 1000000000) != 0) break; ++ret; // fallthrough
288   default: { DBUG_ASSERT(FALSE); }
289   }
290   return ret;
291 }
292 
293 
294 /*
295   Get maximum value for given precision and scale
296 
297   SYNOPSIS
298     max_decimal()
299     precision/scale - see decimal_bin_size() below
300     to              - decimal where where the result will be stored
301                       to->buf and to->len must be set.
302 */
303 
max_decimal(int precision,int frac,decimal_t * to)304 void max_decimal(int precision, int frac, decimal_t *to)
305 {
306   int intpart;
307   dec1 *buf= to->buf;
308   DBUG_ASSERT(precision && precision >= frac);
309 
310   to->sign= 0;
311   if ((intpart= to->intg= (precision - frac)))
312   {
313     int firstdigits= intpart % DIG_PER_DEC1;
314     if (firstdigits)
315       *buf++= powers10[firstdigits] - 1; /* get 9 99 999 ... */
316     for(intpart/= DIG_PER_DEC1; intpart; intpart--)
317       *buf++= DIG_MAX;
318   }
319 
320   if ((to->frac= frac))
321   {
322     int lastdigits= frac % DIG_PER_DEC1;
323     for(frac/= DIG_PER_DEC1; frac; frac--)
324       *buf++= DIG_MAX;
325     if (lastdigits)
326       *buf= frac_max[lastdigits - 1];
327   }
328 }
329 
330 
remove_leading_zeroes(const decimal_t * from,int * intg_result)331 static dec1 *remove_leading_zeroes(const decimal_t *from, int *intg_result)
332 {
333   int intg= from->intg, i;
334   dec1 *buf0= from->buf;
335   i= ((intg - 1) % DIG_PER_DEC1) + 1;
336   while (intg > 0 && *buf0 == 0)
337   {
338     intg-= i;
339     i= DIG_PER_DEC1;
340     buf0++;
341   }
342   if (intg > 0)
343   {
344     intg-= count_leading_zeroes((intg - 1) % DIG_PER_DEC1, *buf0);
345     DBUG_ASSERT(intg > 0);
346   }
347   else
348     intg=0;
349   *intg_result= intg;
350   return buf0;
351 }
352 
353 
354 /*
355   Count actual length of fraction part (without ending zeroes)
356 
357   SYNOPSIS
358     decimal_actual_fraction()
359     from    number for processing
360 */
361 
decimal_actual_fraction(decimal_t * from)362 int decimal_actual_fraction(decimal_t *from)
363 {
364   int frac= from->frac, i;
365   dec1 *buf0= from->buf + ROUND_UP(from->intg) + ROUND_UP(frac) - 1;
366 
367   if (frac == 0)
368     return 0;
369 
370   i= ((frac - 1) % DIG_PER_DEC1 + 1);
371   while (frac > 0 && *buf0 == 0)
372   {
373     frac-= i;
374     i= DIG_PER_DEC1;
375     buf0--;
376   }
377   if (frac > 0)
378   {
379     frac-=
380       count_trailing_zeroes(DIG_PER_DEC1 - ((frac - 1) % DIG_PER_DEC1), *buf0);
381   }
382   return frac;
383 }
384 
385 
386 /*
387   Convert decimal to its printable string representation
388 
389   SYNOPSIS
390     decimal2string()
391       from            - value to convert
392       to              - points to buffer where string representation
393                         should be stored
394       *to_len         - in:  size of to buffer (incl. terminating '\0')
395                         out: length of the actually written string (excl. '\0')
396       fixed_precision - 0 if representation can be variable length and
397                         fixed_decimals will not be checked in this case.
398                         Put number as with fixed point position with this
399                         number of digits (sign counted and decimal point is
400                         counted)
401       fixed_decimals  - number digits after point.
402       filler          - character to fill gaps in case of fixed_precision > 0
403 
404   RETURN VALUE
405     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
406 */
407 
decimal2string(const decimal_t * from,char * to,int * to_len,int fixed_precision,int fixed_decimals,char filler)408 int decimal2string(const decimal_t *from, char *to, int *to_len,
409                    int fixed_precision, int fixed_decimals,
410                    char filler)
411 {
412   /* {intg_len, frac_len} output widths; {intg, frac} places in input */
413   int len, intg, frac= from->frac, i, intg_len, frac_len, fill;
414   /* number digits before decimal point */
415   int fixed_intg= (fixed_precision ?
416                    (fixed_precision - fixed_decimals) : 0);
417   int error=E_DEC_OK;
418   char *s=to;
419   dec1 *buf, *buf0=from->buf, tmp;
420 
421   DBUG_ASSERT(*to_len >= 2+from->sign);
422 
423   /* removing leading zeroes */
424   buf0= remove_leading_zeroes(from, &intg);
425   if (unlikely(intg+frac==0))
426   {
427     intg=1;
428     tmp=0;
429     buf0=&tmp;
430   }
431 
432   if (!(intg_len= fixed_precision ? fixed_intg : intg))
433     intg_len= 1;
434   frac_len= fixed_precision ? fixed_decimals : frac;
435   len= from->sign + intg_len + MY_TEST(frac) + frac_len;
436   if (fixed_precision)
437   {
438     if (frac > fixed_decimals)
439     {
440       error= E_DEC_TRUNCATED;
441       frac= fixed_decimals;
442     }
443     if (intg > fixed_intg)
444     {
445       error= E_DEC_OVERFLOW;
446       intg= fixed_intg;
447     }
448   }
449   else if (unlikely(len > --*to_len)) /* reserve one byte for \0 */
450   {
451     int j= len - *to_len;             /* excess printable chars */
452     error= (frac && j <= frac + 1) ? E_DEC_TRUNCATED : E_DEC_OVERFLOW;
453 
454     /*
455       If we need to cut more places than frac is wide, we'll end up
456       dropping the decimal point as well.  Account for this.
457     */
458     if (frac && j >= frac + 1)
459       j--;
460 
461     if (j > frac)
462     {
463       intg_len= intg-= j-frac;
464       frac= 0;
465     }
466     else
467       frac-=j;
468     frac_len= frac;
469     len= from->sign + intg_len + MY_TEST(frac) + frac_len;
470   }
471   *to_len= len;
472   s[len]= 0;
473 
474   if (from->sign)
475     *s++='-';
476 
477   if (frac)
478   {
479     char *s1= s + intg_len;
480     fill= frac_len - frac;
481     buf=buf0+ROUND_UP(intg);
482     *s1++='.';
483     for (; frac>0; frac-=DIG_PER_DEC1)
484     {
485       dec1 x=*buf++;
486       for (i= MY_MIN(frac, DIG_PER_DEC1); i; i--)
487       {
488         dec1 y=x/DIG_MASK;
489         *s1++='0'+(uchar)y;
490         x-=y*DIG_MASK;
491         x*=10;
492       }
493     }
494     for(; fill > 0; fill--)
495       *s1++=filler;
496   }
497 
498   fill= intg_len - intg;
499   if (intg == 0)
500     fill--; /* symbol 0 before digital point */
501   for(; fill > 0; fill--)
502     *s++=filler;
503   if (intg)
504   {
505     s+=intg;
506     for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
507     {
508       dec1 x=*--buf;
509       for (i= MY_MIN(intg, DIG_PER_DEC1); i; i--)
510       {
511         dec1 y=x/10;
512         *--s='0'+(uchar)(x-y*10);
513         x=y;
514       }
515     }
516   }
517   else
518     *s= '0';
519 
520   return error;
521 }
522 
523 
524 /*
525   Return bounds of decimal digits in the number
526 
527   SYNOPSIS
528     digits_bounds()
529       from         - decimal number for processing
530       start_result - index (from 0 ) of first decimal digits will
531                      be written by this address
532       end_result   - index of position just after last decimal digit
533                      be written by this address
534 */
535 
digits_bounds(decimal_t * from,int * start_result,int * end_result)536 static void digits_bounds(decimal_t *from, int *start_result, int *end_result)
537 {
538   int start, stop, i;
539   dec1 *buf_beg= from->buf;
540   dec1 *end= from->buf + ROUND_UP(from->intg) + ROUND_UP(from->frac);
541   dec1 *buf_end= end - 1;
542 
543   /* find non-zero digit from number begining */
544   while (buf_beg < end && *buf_beg == 0)
545     buf_beg++;
546 
547   if (buf_beg >= end)
548   {
549     /* it is zero */
550     *start_result= *end_result= 0;
551     return;
552   }
553 
554   /* find non-zero decimal digit from number begining */
555   if (buf_beg == from->buf && from->intg)
556   {
557     start= DIG_PER_DEC1 - (i= ((from->intg-1) % DIG_PER_DEC1 + 1));
558     i--;
559   }
560   else
561   {
562     i= DIG_PER_DEC1 - 1;
563     start= (int) ((buf_beg - from->buf) * DIG_PER_DEC1);
564   }
565   if (buf_beg < end)
566     start+= count_leading_zeroes(i, *buf_beg);
567 
568   *start_result= start; /* index of first decimal digit (from 0) */
569 
570   /* find non-zero digit at the end */
571   while (buf_end > buf_beg  && *buf_end == 0)
572     buf_end--;
573   /* find non-zero decimal digit from the end */
574   if (buf_end == end - 1 && from->frac)
575   {
576     stop= (int) (((buf_end - from->buf) * DIG_PER_DEC1 +
577            (i= ((from->frac - 1) % DIG_PER_DEC1 + 1))));
578     i= DIG_PER_DEC1 - i + 1;
579   }
580   else
581   {
582     stop= (int) ((buf_end - from->buf + 1) * DIG_PER_DEC1);
583     i= 1;
584   }
585   stop-= count_trailing_zeroes(i, *buf_end);
586   *end_result= stop; /* index of position after last decimal digit (from 0) */
587 }
588 
589 
590 /*
591   Left shift for alignment of data in buffer
592 
593   SYNOPSIS
594     do_mini_left_shift()
595     dec     pointer to decimal number which have to be shifted
596     shift   number of decimal digits on which it should be shifted
597     beg/end bounds of decimal digits (see digits_bounds())
598 
599   NOTE
600     Result fitting in the buffer should be garanted.
601     'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
602 */
603 
do_mini_left_shift(decimal_t * dec,int shift,int beg,int last)604 void do_mini_left_shift(decimal_t *dec, int shift, int beg, int last)
605 {
606   dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
607   dec1 *end= dec->buf + ROUND_UP(last) - 1;
608   int c_shift= DIG_PER_DEC1 - shift;
609   DBUG_ASSERT(from >= dec->buf);
610   DBUG_ASSERT(end < dec->buf + dec->len);
611   if (beg % DIG_PER_DEC1 < shift)
612     *(from - 1)= (*from) / powers10[c_shift];
613   for(; from < end; from++)
614     *from= ((*from % powers10[c_shift]) * powers10[shift] +
615             (*(from + 1)) / powers10[c_shift]);
616   *from= (*from % powers10[c_shift]) * powers10[shift];
617 }
618 
619 
620 /*
621   Right shift for alignment of data in buffer
622 
623   SYNOPSIS
624     do_mini_left_shift()
625     dec     pointer to decimal number which have to be shifted
626     shift   number of decimal digits on which it should be shifted
627     beg/end bounds of decimal digits (see digits_bounds())
628 
629   NOTE
630     Result fitting in the buffer should be garanted.
631     'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
632 */
633 
do_mini_right_shift(decimal_t * dec,int shift,int beg,int last)634 void do_mini_right_shift(decimal_t *dec, int shift, int beg, int last)
635 {
636   dec1 *from= dec->buf + ROUND_UP(last) - 1;
637   dec1 *end= dec->buf + ROUND_UP(beg + 1) - 1;
638   int c_shift= DIG_PER_DEC1 - shift;
639   DBUG_ASSERT(from < dec->buf + dec->len);
640   DBUG_ASSERT(end >= dec->buf);
641   if (DIG_PER_DEC1 - ((last - 1) % DIG_PER_DEC1 + 1) < shift)
642     *(from + 1)= (*from % powers10[shift]) * powers10[c_shift];
643   for(; from > end; from--)
644     *from= (*from / powers10[shift] +
645             (*(from - 1) % powers10[shift]) * powers10[c_shift]);
646   *from= *from / powers10[shift];
647 }
648 
649 
650 /*
651   Shift of decimal digits in given number (with rounding if it need)
652 
653   SYNOPSIS
654     decimal_shift()
655     dec       number to be shifted
656     shift     number of decimal positions
657               shift > 0 means shift to left shift
658               shift < 0 meand right shift
659   NOTE
660     In fact it is multipling on 10^shift.
661   RETURN
662     E_DEC_OK          OK
663     E_DEC_OVERFLOW    operation lead to overflow, number is untoched
664     E_DEC_TRUNCATED   number was rounded to fit into buffer
665 */
666 
decimal_shift(decimal_t * dec,int shift)667 int decimal_shift(decimal_t *dec, int shift)
668 {
669   /* index of first non zero digit (all indexes from 0) */
670   int beg;
671   /* index of position after last decimal digit */
672   int end;
673   /* index of digit position just after point */
674   int point= ROUND_UP(dec->intg) * DIG_PER_DEC1;
675   /* new point position */
676   int new_point= point + shift;
677   /* number of digits in result */
678   int digits_int, digits_frac;
679   /* length of result and new fraction in big digits*/
680   int new_len, new_frac_len;
681   /* return code */
682   int err= E_DEC_OK;
683   int new_front;
684 
685   if (shift == 0)
686     return E_DEC_OK;
687 
688   digits_bounds(dec, &beg, &end);
689 
690   if (beg == end)
691   {
692     decimal_make_zero(dec);
693     return E_DEC_OK;
694   }
695 
696   digits_int= new_point - beg;
697   set_if_bigger(digits_int, 0);
698   digits_frac= end - new_point;
699   set_if_bigger(digits_frac, 0);
700 
701   if ((new_len= ROUND_UP(digits_int) + (new_frac_len= ROUND_UP(digits_frac))) >
702       dec->len)
703   {
704     int lack= new_len - dec->len;
705     int diff;
706 
707     if (new_frac_len < lack)
708       return E_DEC_OVERFLOW; /* lack more then we have in fraction */
709 
710     /* cat off fraction part to allow new number to fit in our buffer */
711     err= E_DEC_TRUNCATED;
712     new_frac_len-= lack;
713     diff= digits_frac - (new_frac_len * DIG_PER_DEC1);
714     /* Make rounding method as parameter? */
715     decimal_round(dec, dec, end - point - diff, HALF_UP);
716     end-= diff;
717     digits_frac= new_frac_len * DIG_PER_DEC1;
718 
719     if (end <= beg)
720     {
721       /*
722         we lost all digits (they will be shifted out of buffer), so we can
723         just return 0
724       */
725       decimal_make_zero(dec);
726       return E_DEC_TRUNCATED;
727     }
728   }
729 
730   if (shift % DIG_PER_DEC1)
731   {
732     int l_mini_shift, r_mini_shift, mini_shift;
733     int do_left;
734     /*
735       Calculate left/right shift to align decimal digits inside our bug
736       digits correctly
737     */
738     if (shift > 0)
739     {
740       l_mini_shift= shift % DIG_PER_DEC1;
741       r_mini_shift= DIG_PER_DEC1 - l_mini_shift;
742       /*
743         It is left shift so prefer left shift, but if we have not place from
744         left, we have to have it from right, because we checked length of
745         result
746       */
747       do_left= l_mini_shift <= beg;
748       DBUG_ASSERT(do_left || (dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
749     }
750     else
751     {
752       r_mini_shift= (-shift) % DIG_PER_DEC1;
753       l_mini_shift= DIG_PER_DEC1 - r_mini_shift;
754       /* see comment above */
755       do_left= !((dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
756       DBUG_ASSERT(!do_left || l_mini_shift <= beg);
757     }
758     if (do_left)
759     {
760       do_mini_left_shift(dec, l_mini_shift, beg, end);
761       mini_shift= -l_mini_shift;
762     }
763     else
764     {
765       do_mini_right_shift(dec, r_mini_shift, beg, end);
766       mini_shift= r_mini_shift;
767     }
768     new_point+= mini_shift;
769     /*
770       If number is shifted and correctly aligned in buffer we can
771       finish
772     */
773     if (!(shift+= mini_shift) && (new_point - digits_int) < DIG_PER_DEC1)
774     {
775       dec->intg= digits_int;
776       dec->frac= digits_frac;
777       return err;                 /* already shifted as it should be */
778     }
779     beg+= mini_shift;
780     end+= mini_shift;
781   }
782 
783   /* if new 'decimal front' is in first digit, we do not need move digits */
784   if ((new_front= (new_point - digits_int)) >= DIG_PER_DEC1 ||
785       new_front < 0)
786   {
787     /* need to move digits */
788     int d_shift;
789     dec1 *to, *barier;
790     if (new_front > 0)
791     {
792       /* move left */
793       d_shift= new_front / DIG_PER_DEC1;
794       to= dec->buf + (ROUND_UP(beg + 1) - 1 - d_shift);
795       barier= dec->buf + (ROUND_UP(end) - 1 - d_shift);
796       DBUG_ASSERT(to >= dec->buf);
797       DBUG_ASSERT(barier + d_shift < dec->buf + dec->len);
798       for(; to <= barier; to++)
799         *to= *(to + d_shift);
800       for(barier+= d_shift; to <= barier; to++)
801         *to= 0;
802       d_shift= -d_shift;
803     }
804     else
805     {
806       /* move right */
807       d_shift= (1 - new_front) / DIG_PER_DEC1;
808       to= dec->buf + ROUND_UP(end) - 1 + d_shift;
809       barier= dec->buf + ROUND_UP(beg + 1) - 1 + d_shift;
810       DBUG_ASSERT(to < dec->buf + dec->len);
811       DBUG_ASSERT(barier - d_shift >= dec->buf);
812       for(; to >= barier; to--)
813         *to= *(to - d_shift);
814       for(barier-= d_shift; to >= barier; to--)
815         *to= 0;
816     }
817     d_shift*= DIG_PER_DEC1;
818     beg+= d_shift;
819     end+= d_shift;
820     new_point+= d_shift;
821   }
822 
823   /*
824     If there are gaps then fill ren with 0.
825 
826     Only one of following 'for' loops will work becouse beg <= end
827   */
828   beg= ROUND_UP(beg + 1) - 1;
829   end= ROUND_UP(end) - 1;
830   DBUG_ASSERT(new_point >= 0);
831 
832   /* We don't want negative new_point below */
833   if (new_point != 0)
834     new_point= ROUND_UP(new_point) - 1;
835 
836   if (new_point > end)
837   {
838     do
839     {
840       dec->buf[new_point]=0;
841     } while (--new_point > end);
842   }
843   else
844   {
845     for (; new_point < beg; new_point++)
846       dec->buf[new_point]= 0;
847   }
848   dec->intg= digits_int;
849   dec->frac= digits_frac;
850   return err;
851 }
852 
853 
854 /*
855   Convert string to decimal
856 
857   SYNOPSIS
858     internal_str2decl()
859       from    - value to convert. Doesn't have to be \0 terminated!
860       to      - decimal where where the result will be stored
861                 to->buf and to->len must be set.
862       end     - Pointer to pointer to end of string. Will on return be
863 		set to the char after the last used character
864       fixed   - use to->intg, to->frac as limits for input number
865 
866   NOTE
867     to->intg and to->frac can be modified even when fixed=1
868     (but only decreased, in this case)
869 
870   RETURN VALUE
871     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_BAD_NUM/E_DEC_OOM
872     In case of E_DEC_FATAL_ERROR *to is set to decimal zero
873     (to make error handling easier)
874 */
875 
876 int
internal_str2dec(const char * from,decimal_t * to,char ** end,my_bool fixed)877 internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed)
878 {
879   const char *s= from, *s1, *endp, *end_of_string= *end;
880   int i, intg, frac, error, intg1, frac1;
881   dec1 x,*buf;
882   sanity(to);
883 
884   error= E_DEC_BAD_NUM;                         /* In case of bad number */
885   while (s < end_of_string && my_isspace(&my_charset_latin1, *s))
886     s++;
887   if (s == end_of_string)
888     goto fatal_error;
889 
890   if ((to->sign= (*s == '-')))
891     s++;
892   else if (*s == '+')
893     s++;
894 
895   s1=s;
896   while (s < end_of_string && my_isdigit(&my_charset_latin1, *s))
897     s++;
898   intg= (int) (s-s1);
899   if (s < end_of_string && *s=='.')
900   {
901     endp= s+1;
902     while (endp < end_of_string && my_isdigit(&my_charset_latin1, *endp))
903       endp++;
904     frac= (int) (endp - s - 1);
905   }
906   else
907   {
908     frac= 0;
909     endp= s;
910   }
911 
912   *end= (char*) endp;
913 
914   if (frac+intg == 0)
915     goto fatal_error;
916 
917   error= 0;
918   if (fixed)
919   {
920     if (frac > to->frac)
921     {
922       error=E_DEC_TRUNCATED;
923       frac=to->frac;
924     }
925     if (intg > to->intg)
926     {
927       error=E_DEC_OVERFLOW;
928       intg=to->intg;
929     }
930     intg1=ROUND_UP(intg);
931     frac1=ROUND_UP(frac);
932     if (intg1+frac1 > to->len)
933     {
934       error= E_DEC_OOM;
935       goto fatal_error;
936     }
937   }
938   else
939   {
940     intg1=ROUND_UP(intg);
941     frac1=ROUND_UP(frac);
942     FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
943     if (unlikely(error))
944     {
945       frac=frac1*DIG_PER_DEC1;
946       if (error == E_DEC_OVERFLOW)
947         intg=intg1*DIG_PER_DEC1;
948     }
949   }
950   /* Error is guranteed to be set here */
951   to->intg=intg;
952   to->frac=frac;
953 
954   buf=to->buf+intg1;
955   s1=s;
956 
957   for (x=0, i=0; intg; intg--)
958   {
959     x+= (*--s - '0')*powers10[i];
960 
961     if (unlikely(++i == DIG_PER_DEC1))
962     {
963       *--buf=x;
964       x=0;
965       i=0;
966     }
967   }
968   if (i)
969     *--buf=x;
970 
971   buf=to->buf+intg1;
972   for (x=0, i=0; frac; frac--)
973   {
974     x= (*++s1 - '0') + x*10;
975 
976     if (unlikely(++i == DIG_PER_DEC1))
977     {
978       *buf++=x;
979       x=0;
980       i=0;
981     }
982   }
983   if (i)
984     *buf=x*powers10[DIG_PER_DEC1-i];
985 
986   /* Handle exponent */
987   if (endp+1 < end_of_string && (*endp == 'e' || *endp == 'E'))
988   {
989     int str_error;
990     longlong exponent= my_strtoll10(endp+1, (char**) &end_of_string,
991                                     &str_error);
992 
993     if (end_of_string != endp +1)               /* If at least one digit */
994     {
995       *end= (char*) end_of_string;
996       if (str_error > 0)
997       {
998         error= E_DEC_BAD_NUM;
999         goto fatal_error;
1000       }
1001       if (exponent > INT_MAX/2 || (str_error == 0 && exponent < 0))
1002       {
1003         error= E_DEC_OVERFLOW;
1004         goto fatal_error;
1005       }
1006       if (exponent < INT_MIN/2 && error != E_DEC_OVERFLOW)
1007       {
1008         error= E_DEC_TRUNCATED;
1009         goto fatal_error;
1010       }
1011       if (error != E_DEC_OVERFLOW)
1012         error= decimal_shift(to, (int) exponent);
1013     }
1014   }
1015   return error;
1016 
1017 fatal_error:
1018   decimal_make_zero(to);
1019   return error;
1020 }
1021 
1022 
1023 /*
1024   Convert decimal to double
1025 
1026   SYNOPSIS
1027     decimal2double()
1028       from    - value to convert
1029       to      - result will be stored there
1030 
1031   RETURN VALUE
1032     E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1033 */
1034 
decimal2double(const decimal_t * from,double * to)1035 int decimal2double(const decimal_t *from, double *to)
1036 {
1037   char strbuf[FLOATING_POINT_BUFFER], *end;
1038   int len= sizeof(strbuf);
1039   int rc, error;
1040 
1041   rc = decimal2string(from, strbuf, &len, 0, 0, 0);
1042   end= strbuf + len;
1043 
1044   DBUG_PRINT("info", ("interm.: %s", strbuf));
1045 
1046   *to= my_strtod(strbuf, &end, &error);
1047 
1048   DBUG_PRINT("info", ("result: %f", *to));
1049 
1050   return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
1051 }
1052 
1053 /*
1054   Convert double to decimal
1055 
1056   SYNOPSIS
1057     double2decimal()
1058       from    - value to convert
1059       to      - result will be stored there
1060 
1061   RETURN VALUE
1062     E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1063 */
1064 
double2decimal(double from,decimal_t * to)1065 int double2decimal(double from, decimal_t *to)
1066 {
1067   char buff[FLOATING_POINT_BUFFER], *end;
1068   int res;
1069   DBUG_ENTER("double2decimal");
1070   end= buff + my_gcvt(from, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
1071   res= string2decimal(buff, to, &end);
1072   DBUG_PRINT("exit", ("res: %d", res));
1073   DBUG_RETURN(res);
1074 }
1075 
1076 
ull2dec(ulonglong from,decimal_t * to)1077 static int ull2dec(ulonglong from, decimal_t *to)
1078 {
1079   int intg1;
1080   int error= E_DEC_OK;
1081   ulonglong x= from;
1082   dec1 *buf;
1083 
1084   sanity(to);
1085 
1086   if (from == 0)
1087     intg1= 1;
1088   else
1089   {
1090     /* Count the number of decimal_digit_t's we need. */
1091     for (intg1= 0; from != 0; intg1++, from/= DIG_BASE)
1092       ;
1093   }
1094   if (unlikely(intg1 > to->len))
1095   {
1096     intg1= to->len;
1097     error= E_DEC_OVERFLOW;
1098   }
1099   to->frac= 0;
1100   to->intg= intg1 * DIG_PER_DEC1;
1101 
1102   for (buf= to->buf + intg1; intg1; intg1--)
1103   {
1104     ulonglong y= x / DIG_BASE;
1105     *--buf=(dec1)(x - y * DIG_BASE);
1106     x= y;
1107   }
1108   return error;
1109 }
1110 
ulonglong2decimal(ulonglong from,decimal_t * to)1111 int ulonglong2decimal(ulonglong from, decimal_t *to)
1112 {
1113   to->sign=0;
1114   return ull2dec(from, to);
1115 }
1116 
longlong2decimal(longlong from,decimal_t * to)1117 int longlong2decimal(longlong from, decimal_t *to)
1118 {
1119   if ((to->sign= from < 0))
1120     return ull2dec(-from, to);
1121   return ull2dec(from, to);
1122 }
1123 
decimal2ulonglong(decimal_t * from,ulonglong * to)1124 int decimal2ulonglong(decimal_t *from, ulonglong *to)
1125 {
1126   dec1 *buf=from->buf;
1127   ulonglong x=0;
1128   int intg, frac;
1129 
1130   if (from->sign)
1131   {
1132       *to=ULL(0);
1133       return E_DEC_OVERFLOW;
1134   }
1135 
1136   for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1137   {
1138     ulonglong y=x;
1139     x=x*DIG_BASE + *buf++;
1140     if (unlikely(y > ((ulonglong) ULONGLONG_MAX/DIG_BASE) || x < y))
1141     {
1142       *to=ULONGLONG_MAX;
1143       return E_DEC_OVERFLOW;
1144     }
1145   }
1146   *to=x;
1147   for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1148     if (*buf++)
1149       return E_DEC_TRUNCATED;
1150   return E_DEC_OK;
1151 }
1152 
decimal2longlong(decimal_t * from,longlong * to)1153 int decimal2longlong(decimal_t *from, longlong *to)
1154 {
1155   dec1 *buf=from->buf;
1156   longlong x=0;
1157   int intg, frac;
1158 
1159   for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1160   {
1161     longlong y=x;
1162     /*
1163       Attention: trick!
1164       we're calculating -|from| instead of |from| here
1165       because |LONGLONG_MIN| > LONGLONG_MAX
1166       so we can convert -9223372036854775808 correctly
1167     */
1168     x=x*DIG_BASE - *buf++;
1169     if (unlikely(y < (LONGLONG_MIN/DIG_BASE) || x > y))
1170     {
1171       /*
1172         the decimal is bigger than any possible integer
1173         return border integer depending on the sign
1174       */
1175       *to= from->sign ? LONGLONG_MIN : LONGLONG_MAX;
1176       return E_DEC_OVERFLOW;
1177     }
1178   }
1179   /* boundary case: 9223372036854775808 */
1180   if (unlikely(from->sign==0 && x == LONGLONG_MIN))
1181   {
1182     *to= LONGLONG_MAX;
1183     return E_DEC_OVERFLOW;
1184   }
1185 
1186   *to=from->sign ? x : -x;
1187   for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1188     if (*buf++)
1189       return E_DEC_TRUNCATED;
1190   return E_DEC_OK;
1191 }
1192 
1193 
1194 #define LLDIV_MIN -1000000000000000000LL
1195 #define LLDIV_MAX  1000000000000000000LL
1196 
1197 /**
1198   Convert decimal value to lldiv_t value.
1199   @param      from  The decimal value to convert from.
1200   @param OUT  to    The lldiv_t variable to convert to.
1201   @return           0 on success, error code on error.
1202 */
decimal2lldiv_t(const decimal_t * from,lldiv_t * to)1203 int decimal2lldiv_t(const decimal_t *from, lldiv_t *to)
1204 {
1205   int int_part= ROUND_UP(from->intg);
1206   int frac_part= ROUND_UP(from->frac);
1207   if (int_part > 2)
1208   {
1209     to->rem= 0;
1210     to->quot= from->sign ? LLDIV_MIN : LLDIV_MAX;
1211     return E_DEC_OVERFLOW;
1212   }
1213   if (int_part == 2)
1214     to->quot= ((longlong) from->buf[0]) * DIG_BASE + from->buf[1];
1215   else if (int_part == 1)
1216     to->quot= from->buf[0];
1217   else
1218     to->quot= 0;
1219   to->rem= frac_part ? from->buf[int_part] : 0;
1220   if (from->sign)
1221   {
1222     to->quot= -to->quot;
1223     to->rem= -to->rem;
1224   }
1225   return 0;
1226 }
1227 
1228 
1229 /**
1230   Convert double value to lldiv_t valie.
1231   @param     from The double value to convert from.
1232   @param OUT to   The lldit_t variable to convert to.
1233   @return         0 on success, error code on error.
1234 
1235   Integer part goes into lld.quot.
1236   Fractional part multiplied to 1000000000 (10^9) goes to lld.rem.
1237   Typically used in datetime calculations to split seconds
1238   and nanoseconds.
1239 */
double2lldiv_t(double nr,lldiv_t * lld)1240 int double2lldiv_t(double nr, lldiv_t *lld)
1241 {
1242   if (nr > LLDIV_MAX)
1243   {
1244     lld->quot= LLDIV_MAX;
1245     lld->rem= 0;
1246     return E_DEC_OVERFLOW;
1247   }
1248   else if (nr < LLDIV_MIN)
1249   {
1250     lld->quot= LLDIV_MIN;
1251     lld->rem= 0;
1252     return E_DEC_OVERFLOW;
1253   }
1254   /* Truncate fractional part toward zero and store into "quot" */
1255   lld->quot= (longlong) (nr > 0 ? floor(nr) : ceil(nr));
1256   /* Multiply reminder to 10^9 and store into "rem" */
1257   lld->rem= (longlong) rint((nr - (double) lld->quot) * 1000000000);
1258   /*
1259     Sometimes the expression "(double) 0.999999999xxx * (double) 10e9"
1260     gives 1,000,000,000 instead of 999,999,999 due to lack of double precision.
1261     The callers do not expect lld->rem to be greater than 999,999,999.
1262     Let's catch this corner case and put the "nanounit" (e.g. nanosecond)
1263     value in ldd->rem back into the valid range.
1264   */
1265   if (lld->rem > 999999999LL)
1266     lld->rem= 999999999LL;
1267   else if (lld->rem < -999999999LL)
1268     lld->rem= -999999999LL;
1269   return E_DEC_OK;
1270 }
1271 
1272 
1273 
1274 /*
1275   Convert decimal to its binary fixed-length representation
1276   two representations of the same length can be compared with memcmp
1277   with the correct -1/0/+1 result
1278 
1279   SYNOPSIS
1280     decimal2bin()
1281       from    - value to convert
1282       to      - points to buffer where string representation should be stored
1283       precision/scale - see decimal_bin_size() below
1284 
1285   NOTE
1286     the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1287 
1288   RETURN VALUE
1289     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1290 
1291   DESCRIPTION
1292     for storage decimal numbers are converted to the "binary" format.
1293 
1294     This format has the following properties:
1295       1. length of the binary representation depends on the {precision, scale}
1296       as provided by the caller and NOT on the intg/frac of the decimal to
1297       convert.
1298       2. binary representations of the same {precision, scale} can be compared
1299       with memcmp - with the same result as decimal_cmp() of the original
1300       decimals (not taking into account possible precision loss during
1301       conversion).
1302 
1303     This binary format is as follows:
1304       1. First the number is converted to have a requested precision and scale.
1305       2. Every full DIG_PER_DEC1 digits of intg part are stored in 4 bytes
1306          as is
1307       3. The first intg % DIG_PER_DEC1 digits are stored in the reduced
1308          number of bytes (enough bytes to store this number of digits -
1309          see dig2bytes)
1310       4. same for frac - full decimal_digit_t's are stored as is,
1311          the last frac % DIG_PER_DEC1 digits - in the reduced number of bytes.
1312       5. If the number is negative - every byte is inversed.
1313       5. The very first bit of the resulting byte array is inverted (because
1314          memcmp compares unsigned bytes, see property 2 above)
1315 
1316     Example:
1317 
1318       1234567890.1234
1319 
1320     internally is represented as 3 decimal_digit_t's
1321 
1322       1 234567890 123400000
1323 
1324     (assuming we want a binary representation with precision=14, scale=4)
1325     in hex it's
1326 
1327       00-00-00-01  0D-FB-38-D2  07-5A-EF-40
1328 
1329     now, middle decimal_digit_t is full - it stores 9 decimal digits. It goes
1330     into binary representation as is:
1331 
1332 
1333       ...........  0D-FB-38-D2 ............
1334 
1335     First decimal_digit_t has only one decimal digit. We can store one digit in
1336     one byte, no need to waste four:
1337 
1338                 01 0D-FB-38-D2 ............
1339 
1340     now, last digit. It's 123400000. We can store 1234 in two bytes:
1341 
1342                 01 0D-FB-38-D2 04-D2
1343 
1344     So, we've packed 12 bytes number in 7 bytes.
1345     And now we invert the highest bit to get the final result:
1346 
1347                 81 0D FB 38 D2 04 D2
1348 
1349     And for -1234567890.1234 it would be
1350 
1351                 7E F2 04 C7 2D FB 2D
1352 */
decimal2bin(decimal_t * from,uchar * to,int precision,int frac)1353 int decimal2bin(decimal_t *from, uchar *to, int precision, int frac)
1354 {
1355   dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
1356   int error=E_DEC_OK, intg=precision-frac,
1357       isize1, intg1, intg1x, from_intg,
1358       intg0=intg/DIG_PER_DEC1,
1359       frac0=frac/DIG_PER_DEC1,
1360       intg0x=intg-intg0*DIG_PER_DEC1,
1361       frac0x=frac-frac0*DIG_PER_DEC1,
1362       frac1=from->frac/DIG_PER_DEC1,
1363       frac1x=from->frac-frac1*DIG_PER_DEC1,
1364       isize0=intg0*sizeof(dec1)+dig2bytes[intg0x],
1365       fsize0=frac0*sizeof(dec1)+dig2bytes[frac0x],
1366       fsize1=frac1*sizeof(dec1)+dig2bytes[frac1x];
1367   const int orig_isize0= isize0;
1368   const int orig_fsize0= fsize0;
1369   uchar *orig_to= to;
1370 
1371   buf1= remove_leading_zeroes(from, &from_intg);
1372 
1373   if (unlikely(from_intg+fsize1==0))
1374   {
1375     mask=0; /* just in case */
1376     intg=1;
1377     buf1=&mask;
1378   }
1379 
1380   intg1=from_intg/DIG_PER_DEC1;
1381   intg1x=from_intg-intg1*DIG_PER_DEC1;
1382   isize1=intg1*sizeof(dec1)+dig2bytes[intg1x];
1383 
1384   if (intg < from_intg)
1385   {
1386     buf1+=intg1-intg0+(intg1x>0)-(intg0x>0);
1387     intg1=intg0; intg1x=intg0x;
1388     error=E_DEC_OVERFLOW;
1389   }
1390   else if (isize0 > isize1)
1391   {
1392     while (isize0-- > isize1)
1393       *to++= (char)mask;
1394   }
1395   if (fsize0 < fsize1)
1396   {
1397     frac1=frac0; frac1x=frac0x;
1398     error=E_DEC_TRUNCATED;
1399   }
1400   else if (fsize0 > fsize1 && frac1x)
1401   {
1402     if (frac0 == frac1)
1403     {
1404       frac1x=frac0x;
1405       fsize0= fsize1;
1406     }
1407     else
1408     {
1409       frac1++;
1410       frac1x=0;
1411     }
1412   }
1413 
1414   /* intg1x part */
1415   if (intg1x)
1416   {
1417     int i=dig2bytes[intg1x];
1418     dec1 x=(*buf1++ % powers10[intg1x]) ^ mask;
1419     switch (i)
1420     {
1421       case 1: mi_int1store(to, x); break;
1422       case 2: mi_int2store(to, x); break;
1423       case 3: mi_int3store(to, x); break;
1424       case 4: mi_int4store(to, x); break;
1425       default: DBUG_ASSERT(0);
1426     }
1427     to+=i;
1428   }
1429 
1430   /* intg1+frac1 part */
1431   for (stop1=buf1+intg1+frac1; buf1 < stop1; to+=sizeof(dec1))
1432   {
1433     dec1 x=*buf1++ ^ mask;
1434     DBUG_ASSERT(sizeof(dec1) == 4);
1435     mi_int4store(to, x);
1436   }
1437 
1438   /* frac1x part */
1439   if (frac1x)
1440   {
1441     dec1 x;
1442     int i=dig2bytes[frac1x],
1443         lim=(frac1 < frac0 ? DIG_PER_DEC1 : frac0x);
1444     while (frac1x < lim && dig2bytes[frac1x] == i)
1445       frac1x++;
1446     x=(*buf1 / powers10[DIG_PER_DEC1 - frac1x]) ^ mask;
1447     switch (i)
1448     {
1449       case 1: mi_int1store(to, x); break;
1450       case 2: mi_int2store(to, x); break;
1451       case 3: mi_int3store(to, x); break;
1452       case 4: mi_int4store(to, x); break;
1453       default: DBUG_ASSERT(0);
1454     }
1455     to+=i;
1456   }
1457   if (fsize0 > fsize1)
1458   {
1459     uchar *to_end= orig_to + orig_fsize0 + orig_isize0;
1460 
1461     while (fsize0-- > fsize1 && to < to_end)
1462       *to++= (uchar)mask;
1463   }
1464   orig_to[0]^= 0x80;
1465 
1466   /* Check that we have written the whole decimal and nothing more */
1467   DBUG_ASSERT(to == orig_to + orig_fsize0 + orig_isize0);
1468   return error;
1469 }
1470 
1471 /*
1472   Restores decimal from its binary fixed-length representation
1473 
1474   SYNOPSIS
1475     bin2decimal()
1476       from    - value to convert
1477       to      - result
1478       precision/scale - see decimal_bin_size() below
1479 
1480   NOTE
1481     see decimal2bin()
1482     the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1483 
1484   RETURN VALUE
1485     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1486 */
1487 
bin2decimal(const uchar * from,decimal_t * to,int precision,int scale)1488 int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale)
1489 {
1490   int error=E_DEC_OK, intg=precision-scale,
1491       intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1492       intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1,
1493       intg1=intg0+(intg0x>0), frac1=frac0+(frac0x>0);
1494   dec1 *buf=to->buf, mask=(*from & 0x80) ? 0 : -1;
1495   const uchar *stop;
1496   uchar *d_copy;
1497   int bin_size= decimal_bin_size(precision, scale);
1498 
1499   sanity(to);
1500   d_copy= (uchar*) my_alloca(bin_size);
1501   memcpy(d_copy, from, bin_size);
1502   d_copy[0]^= 0x80;
1503   from= d_copy;
1504 
1505   FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
1506   if (unlikely(error))
1507   {
1508     if (intg1 < intg0+(intg0x>0))
1509     {
1510       from+=dig2bytes[intg0x]+sizeof(dec1)*(intg0-intg1);
1511       frac0=frac0x=intg0x=0;
1512       intg0=intg1;
1513     }
1514     else
1515     {
1516       frac0x=0;
1517       frac0=frac1;
1518     }
1519   }
1520 
1521   to->sign=(mask != 0);
1522   to->intg=intg0*DIG_PER_DEC1+intg0x;
1523   to->frac=frac0*DIG_PER_DEC1+frac0x;
1524 
1525   if (intg0x)
1526   {
1527     int i=dig2bytes[intg0x];
1528     dec1 UNINIT_VAR(x);
1529     switch (i)
1530     {
1531       case 1: x=mi_sint1korr(from); break;
1532       case 2: x=mi_sint2korr(from); break;
1533       case 3: x=mi_sint3korr(from); break;
1534       case 4: x=mi_sint4korr(from); break;
1535       default: DBUG_ASSERT(0);
1536     }
1537     from+=i;
1538     *buf=x ^ mask;
1539     if (((ulonglong)*buf) >= (ulonglong) powers10[intg0x+1])
1540       goto err;
1541     if (buf > to->buf || *buf != 0)
1542       buf++;
1543     else
1544       to->intg-=intg0x;
1545   }
1546   for (stop=from+intg0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1547   {
1548     DBUG_ASSERT(sizeof(dec1) == 4);
1549     *buf=mi_sint4korr(from) ^ mask;
1550     if (((uint32)*buf) > DIG_MAX)
1551       goto err;
1552     if (buf > to->buf || *buf != 0)
1553       buf++;
1554     else
1555       to->intg-=DIG_PER_DEC1;
1556   }
1557   DBUG_ASSERT(to->intg >=0);
1558   for (stop=from+frac0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1559   {
1560     DBUG_ASSERT(sizeof(dec1) == 4);
1561     *buf=mi_sint4korr(from) ^ mask;
1562     if (((uint32)*buf) > DIG_MAX)
1563       goto err;
1564     buf++;
1565   }
1566   if (frac0x)
1567   {
1568     int i=dig2bytes[frac0x];
1569     dec1 UNINIT_VAR(x);
1570     switch (i)
1571     {
1572       case 1: x=mi_sint1korr(from); break;
1573       case 2: x=mi_sint2korr(from); break;
1574       case 3: x=mi_sint3korr(from); break;
1575       case 4: x=mi_sint4korr(from); break;
1576       default: DBUG_ASSERT(0);
1577     }
1578     *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
1579     if (((uint32)*buf) > DIG_MAX)
1580       goto err;
1581     buf++;
1582   }
1583   my_afree(d_copy);
1584 
1585   /*
1586     No digits? We have read the number zero, of unspecified precision.
1587     Make it a proper zero, with non-zero precision.
1588   */
1589   if (to->intg == 0 && to->frac == 0)
1590     decimal_make_zero(to);
1591   return error;
1592 
1593 err:
1594   my_afree(d_copy);
1595   decimal_make_zero(to);
1596   return(E_DEC_BAD_NUM);
1597 }
1598 
1599 /*
1600   Returns the size of array to hold a decimal with given precision and scale
1601 
1602   RETURN VALUE
1603     size in dec1
1604     (multiply by sizeof(dec1) to get the size if bytes)
1605 */
1606 
decimal_size(int precision,int scale)1607 int decimal_size(int precision, int scale)
1608 {
1609   DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
1610   return ROUND_UP(precision-scale)+ROUND_UP(scale);
1611 }
1612 
1613 /*
1614   Returns the size of array to hold a binary representation of a decimal
1615 
1616   RETURN VALUE
1617     size in bytes
1618 */
1619 
decimal_bin_size(int precision,int scale)1620 int decimal_bin_size(int precision, int scale)
1621 {
1622   int intg=precision-scale,
1623       intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1624       intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1;
1625 
1626   DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
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), UNINIT_VAR(round_digit),
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   return from1->sign > from2->sign ? -1 : 1;
2141 }
2142 
decimal_is_zero(const decimal_t * from)2143 int decimal_is_zero(const decimal_t *from)
2144 {
2145   dec1 *buf1=from->buf,
2146        *end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
2147   while (buf1 < end)
2148     if (*buf1++)
2149       return 0;
2150   return 1;
2151 }
2152 
2153 /*
2154   multiply two decimals
2155 
2156   SYNOPSIS
2157     decimal_mul()
2158       from1, from2 - factors
2159       to      - product
2160 
2161   RETURN VALUE
2162     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW;
2163 
2164   NOTES
2165     in this implementation, with sizeof(dec1)=4 we have DIG_PER_DEC1=9,
2166     and 63-digit number will take only 7 dec1 words (basically a 7-digit
2167     "base 999999999" number).  Thus there's no need in fast multiplication
2168     algorithms, 7-digit numbers can be multiplied with a naive O(n*n)
2169     method.
2170 
2171     XXX if this library is to be used with huge numbers of thousands of
2172     digits, fast multiplication must be implemented.
2173 */
decimal_mul(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2174 int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2175 {
2176   int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
2177       frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
2178       intg0=ROUND_UP(from1->intg+from2->intg),
2179       frac0=frac1+frac2, error, iii, jjj, d_to_move;
2180   dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
2181        *start2, *stop2, *stop1, *start0, carry;
2182 
2183   sanity(to);
2184 
2185   iii= intg0;                                       /* save 'ideal' values */
2186   jjj= frac0;
2187   FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);  /* bound size */
2188   to->sign= from1->sign != from2->sign;
2189   to->frac= from1->frac + from2->frac;              /* store size in digits */
2190   set_if_smaller(to->frac, NOT_FIXED_DEC);
2191   to->intg=intg0*DIG_PER_DEC1;
2192 
2193   if (unlikely(error))
2194   {
2195     set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
2196     set_if_smaller(to->intg, intg0*DIG_PER_DEC1);
2197     if (unlikely(iii > intg0))                     /* bounded integer-part */
2198     {
2199       iii-=intg0;
2200       jjj= iii >> 1;
2201       intg1-= jjj;
2202       intg2-=iii-jjj;
2203       frac1=frac2=0; /* frac0 is already 0 here */
2204     }
2205     else                                         /* bounded fract part */
2206     {
2207       jjj-=frac0;
2208       iii=jjj >> 1;
2209       if (frac1 <= frac2)
2210       {
2211         frac1-= iii;
2212         frac2-=jjj-iii;
2213       }
2214       else
2215       {
2216         frac2-= iii;
2217         frac1-=jjj-iii;
2218       }
2219     }
2220   }
2221   start0=to->buf+intg0+frac0-1;
2222   start2=buf2+frac2-1;
2223   stop1=buf1-intg1;
2224   stop2=buf2-intg2;
2225 
2226   memset(to->buf, 0, (intg0+frac0)*sizeof(dec1));
2227 
2228   for (buf1+=frac1-1; buf1 >= stop1; buf1--, start0--)
2229   {
2230     carry=0;
2231     for (buf0=start0, buf2=start2; buf2 >= stop2; buf2--, buf0--)
2232     {
2233       dec1 hi, lo;
2234       dec2 p= ((dec2)*buf1) * ((dec2)*buf2);
2235       hi=(dec1)(p/DIG_BASE);
2236       lo=(dec1)(p-((dec2)hi)*DIG_BASE);
2237       ADD2(*buf0, *buf0, lo, carry);
2238       carry+=hi;
2239     }
2240     if (carry)
2241     {
2242       if (buf0 < to->buf)
2243         return E_DEC_OVERFLOW;
2244       ADD2(*buf0, *buf0, 0, carry);
2245     }
2246     for (buf0--; carry; buf0--)
2247     {
2248       if (buf0 < to->buf)
2249         return E_DEC_OVERFLOW;
2250       ADD(*buf0, *buf0, 0, carry);
2251     }
2252   }
2253 
2254   /* Now we have to check for -0.000 case */
2255   if (to->sign)
2256   {
2257     dec1 *buf= to->buf;
2258     dec1 *end= to->buf + intg0 + frac0;
2259     DBUG_ASSERT(buf != end);
2260     for (;;)
2261     {
2262       if (*buf)
2263         break;
2264       if (++buf == end)
2265       {
2266         /* We got decimal zero */
2267         decimal_make_zero(to);
2268         break;
2269       }
2270     }
2271   }
2272   buf1= to->buf;
2273   d_to_move= intg0 + ROUND_UP(to->frac);
2274   while (!*buf1 && (to->intg > DIG_PER_DEC1))
2275   {
2276     buf1++;
2277     to->intg-= DIG_PER_DEC1;
2278     d_to_move--;
2279   }
2280   if (to->buf < buf1)
2281   {
2282     dec1 *cur_d= to->buf;
2283     for (; d_to_move--; cur_d++, buf1++)
2284       *cur_d= *buf1;
2285   }
2286   return error;
2287 }
2288 
2289 /*
2290   naive division algorithm (Knuth's Algorithm D in 4.3.1) -
2291   it's ok for short numbers
2292   also we're using alloca() to allocate a temporary buffer
2293 
2294   XXX if this library is to be used with huge numbers of thousands of
2295   digits, fast division must be implemented and alloca should be
2296   changed to malloc (or at least fallback to malloc if alloca() fails)
2297   but then, decimal_mul() should be rewritten too :(
2298 */
do_div_mod(const decimal_t * from1,const decimal_t * from2,decimal_t * to,decimal_t * mod,int scale_incr)2299 static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
2300                       decimal_t *to, decimal_t *mod, int scale_incr)
2301 {
2302   int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2303       frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2304       UNINIT_VAR(error), i, intg0, frac0, len1, len2, dintg, div_mod=(!mod);
2305   dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1,
2306        *start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry;
2307   dec2 norm_factor, x, guess, y;
2308 
2309   if (mod)
2310     to=mod;
2311 
2312   sanity(to);
2313 
2314   /* removing all the leading zeroes */
2315   i= ((prec2 - 1) % DIG_PER_DEC1) + 1;
2316   while (prec2 > 0 && *buf2 == 0)
2317   {
2318     prec2-= i;
2319     i= DIG_PER_DEC1;
2320     buf2++;
2321   }
2322   if (prec2 <= 0) /* short-circuit everything: from2 == 0 */
2323     return E_DEC_DIV_ZERO;
2324   prec2-= count_leading_zeroes((prec2 - 1) % DIG_PER_DEC1, *buf2);
2325   DBUG_ASSERT(prec2 > 0);
2326 
2327   i=((prec1-1) % DIG_PER_DEC1)+1;
2328   while (prec1 > 0 && *buf1 == 0)
2329   {
2330     prec1-=i;
2331     i=DIG_PER_DEC1;
2332     buf1++;
2333   }
2334   if (prec1 <= 0)
2335   { /* short-circuit everything: from1 == 0 */
2336     decimal_make_zero(to);
2337     return E_DEC_OK;
2338   }
2339   prec1-= count_leading_zeroes((prec1-1) % DIG_PER_DEC1, *buf1);
2340   DBUG_ASSERT(prec1 > 0);
2341 
2342   /* let's fix scale_incr, taking into account frac1,frac2 increase */
2343   if ((scale_incr-= frac1 - from1->frac + frac2 - from2->frac) < 0)
2344     scale_incr=0;
2345 
2346   dintg=(prec1-frac1)-(prec2-frac2)+(*buf1 >= *buf2);
2347   if (dintg < 0)
2348   {
2349     dintg/=DIG_PER_DEC1;
2350     intg0=0;
2351   }
2352   else
2353     intg0=ROUND_UP(dintg);
2354   if (mod)
2355   {
2356     /* we're calculating N1 % N2.
2357        The result will have
2358          frac=max(frac1, frac2), as for subtraction
2359          intg=intg2
2360     */
2361     to->sign=from1->sign;
2362     to->frac= MY_MAX(from1->frac, from2->frac);
2363     frac0=0;
2364   }
2365   else
2366   {
2367     /*
2368       we're calculating N1/N2. N1 is in the buf1, has prec1 digits
2369       N2 is in the buf2, has prec2 digits. Scales are frac1 and
2370       frac2 accordingly.
2371       Thus, the result will have
2372          frac = ROUND_UP(frac1+frac2+scale_incr)
2373       and
2374          intg = (prec1-frac1) - (prec2-frac2) + 1
2375          prec = intg+frac
2376     */
2377     frac0=ROUND_UP(frac1+frac2+scale_incr);
2378     FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
2379     to->sign=from1->sign != from2->sign;
2380     to->intg=intg0*DIG_PER_DEC1;
2381     to->frac=frac0*DIG_PER_DEC1;
2382   }
2383   buf0=to->buf;
2384   stop0=buf0+intg0+frac0;
2385   if (likely(div_mod))
2386     while (dintg++ < 0 && buf0 < &to->buf[to->len])
2387     {
2388       *buf0++=0;
2389     }
2390 
2391   len1=(i=ROUND_UP(prec1))+ROUND_UP(2*frac2+scale_incr+1) + 1;
2392   set_if_bigger(len1, 3);
2393   if (!(tmp1=(dec1 *)my_alloca(len1*sizeof(dec1))))
2394     return E_DEC_OOM;
2395   memcpy(tmp1, buf1, i*sizeof(dec1));
2396   memset(tmp1+i, 0, (len1-i)*sizeof(dec1));
2397 
2398   start1=tmp1;
2399   stop1=start1+len1;
2400   start2=buf2;
2401   stop2=buf2+ROUND_UP(prec2)-1;
2402 
2403   /* removing end zeroes */
2404   while (*stop2 == 0 && stop2 >= start2)
2405     stop2--;
2406   len2= (int) (stop2++ - start2);
2407 
2408   /*
2409     calculating norm2 (normalized *start2) - we need *start2 to be large
2410     (at least > DIG_BASE/2), but unlike Knuth's Alg. D we don't want to
2411     normalize input numbers (as we don't make a copy of the divisor).
2412     Thus we normalize first dec1 of buf2 only, and we'll normalize *start1
2413     on the fly for the purpose of guesstimation only.
2414     It's also faster, as we're saving on normalization of buf2
2415   */
2416   norm_factor=DIG_BASE/(*start2+1);
2417   norm2=(dec1)(norm_factor*start2[0]);
2418   if (likely(len2>0))
2419     norm2+=(dec1)(norm_factor*start2[1]/DIG_BASE);
2420 
2421   if (*start1 < *start2)
2422     dcarry=*start1++;
2423   else
2424     dcarry=0;
2425 
2426   /* main loop */
2427   for (; buf0 < stop0; buf0++)
2428   {
2429     /* short-circuit, if possible */
2430     if (unlikely(dcarry == 0 && *start1 < *start2))
2431       guess=0;
2432     else
2433     {
2434       /* D3: make a guess */
2435       x=start1[0]+((dec2)dcarry)*DIG_BASE;
2436       y=start1[1];
2437       guess=(norm_factor*x+norm_factor*y/DIG_BASE)/norm2;
2438       if (unlikely(guess >= DIG_BASE))
2439         guess=DIG_BASE-1;
2440       if (likely(len2>0))
2441       {
2442         /* hmm, this is a suspicious trick - I removed normalization here */
2443         if (start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y)
2444           guess--;
2445         if (unlikely(start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y))
2446           guess--;
2447         DBUG_ASSERT(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y);
2448       }
2449 
2450       /* D4: multiply and subtract */
2451       buf2=stop2;
2452       buf1=start1+len2;
2453       DBUG_ASSERT(buf1 < stop1);
2454       for (carry=0; buf2 > start2; buf1--)
2455       {
2456         dec1 hi, lo;
2457         x=guess * (*--buf2);
2458         hi=(dec1)(x/DIG_BASE);
2459         lo=(dec1)(x-((dec2)hi)*DIG_BASE);
2460         SUB2(*buf1, *buf1, lo, carry);
2461         carry+=hi;
2462       }
2463       carry= dcarry < carry;
2464 
2465       /* D5: check the remainder */
2466       if (unlikely(carry))
2467       {
2468         /* D6: correct the guess */
2469         guess--;
2470         buf2=stop2;
2471         buf1=start1+len2;
2472         for (carry=0; buf2 > start2; buf1--)
2473         {
2474           ADD(*buf1, *buf1, *--buf2, carry);
2475         }
2476       }
2477     }
2478     if (likely(div_mod))
2479     {
2480       DBUG_ASSERT(buf0 < to->buf + to->len);
2481       *buf0=(dec1)guess;
2482     }
2483     dcarry= *start1;
2484     start1++;
2485   }
2486   if (mod)
2487   {
2488     /*
2489       now the result is in tmp1, it has
2490         intg=prec1-frac1
2491         frac=max(frac1, frac2)=to->frac
2492     */
2493     if (dcarry)
2494       *--start1=dcarry;
2495     buf0=to->buf;
2496     intg0=(int) (ROUND_UP(prec1-frac1)-(start1-tmp1));
2497     frac0=ROUND_UP(to->frac);
2498     error=E_DEC_OK;
2499     if (unlikely(frac0==0 && intg0==0))
2500     {
2501       decimal_make_zero(to);
2502       goto done;
2503     }
2504     if (intg0<=0)
2505     {
2506       if (unlikely(-intg0 >= to->len))
2507       {
2508         decimal_make_zero(to);
2509         error=E_DEC_TRUNCATED;
2510         goto done;
2511       }
2512       stop1= start1 + frac0 + intg0;
2513       frac0+=intg0;
2514       to->intg=0;
2515       while (intg0++ < 0)
2516         *buf0++=0;
2517     }
2518     else
2519     {
2520       if (unlikely(intg0 > to->len))
2521       {
2522         frac0=0;
2523         intg0=to->len;
2524         error=E_DEC_OVERFLOW;
2525         goto done;
2526       }
2527       DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
2528       stop1=start1+frac0+intg0;
2529       to->intg= MY_MIN(intg0 * DIG_PER_DEC1, from2->intg);
2530     }
2531     if (unlikely(intg0+frac0 > to->len))
2532     {
2533       stop1-=frac0+intg0-to->len;
2534       frac0=to->len-intg0;
2535       to->frac=frac0*DIG_PER_DEC1;
2536         error=E_DEC_TRUNCATED;
2537     }
2538     DBUG_ASSERT(buf0 + (stop1 - start1) <= to->buf + to->len);
2539     while (start1 < stop1)
2540         *buf0++=*start1++;
2541   }
2542 done:
2543   my_afree(tmp1);
2544   tmp1= remove_leading_zeroes(to, &to->intg);
2545   if(to->buf != tmp1)
2546     memmove(to->buf, tmp1,
2547             (ROUND_UP(to->intg) + ROUND_UP(to->frac)) * sizeof(dec1));
2548   return error;
2549 }
2550 
2551 /*
2552   division of two decimals
2553 
2554   SYNOPSIS
2555     decimal_div()
2556       from1   - dividend
2557       from2   - divisor
2558       to      - quotient
2559 
2560   RETURN VALUE
2561     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2562 
2563   NOTES
2564     see do_div_mod()
2565 */
2566 
2567 int
decimal_div(const decimal_t * from1,const decimal_t * from2,decimal_t * to,int scale_incr)2568 decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to,
2569             int scale_incr)
2570 {
2571   return do_div_mod(from1, from2, to, 0, scale_incr);
2572 }
2573 
2574 /*
2575   modulus
2576 
2577   SYNOPSIS
2578     decimal_mod()
2579       from1   - dividend
2580       from2   - divisor
2581       to      - modulus
2582 
2583   RETURN VALUE
2584     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2585 
2586   NOTES
2587     see do_div_mod()
2588 
2589   DESCRIPTION
2590     the modulus R in    R = M mod N
2591 
2592    is defined as
2593 
2594      0 <= |R| < |M|
2595      sign R == sign M
2596      R = M - k*N, where k is integer
2597 
2598    thus, there's no requirement for M or N to be integers
2599 */
2600 
decimal_mod(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2601 int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2602 {
2603   return do_div_mod(from1, from2, 0, to, 0);
2604 }
2605 
2606 #ifdef MAIN
2607 /*
2608   The main() program has been converted into a unit test.
2609  */
2610 #endif
2611