Drizzled Public API Documentation

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