Drizzled Public API Documentation

decimal.cc
Go to the documentation of this file.
00001 /* Copyright (C) 2000 MySQL AB
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00015 
00026 /*
00027 =======================================================================
00028   Quoting the standard
00029   (SQL:2003, Part 2 Foundations, aka ISO/IEC 9075-2:2003)
00030 
00031 4.4.2 Characteristics of numbers, page 27:
00032 
00033   An exact numeric type has a precision P and a scale S. P is a positive
00034   integer that determines the number of significant digits in a
00035   particular radix R, where R is either 2 or 10. S is a non-negative
00036   integer. Every value of an exact numeric type of scale S is of the
00037   form n*10^{-S}, where n is an integer such that ­-R^P <= n <= R^P.
00038 
00039   [...]
00040 
00041   If an assignment of some number would result in a loss of its most
00042   significant digit, an exception condition is raised. If least
00043   significant digits are lost, implementation-defined rounding or
00044   truncating occurs, with no exception condition being raised.
00045 
00046   [...]
00047 
00048   Whenever an exact or approximate numeric value is assigned to an exact
00049   numeric value site, an approximation of its value that preserves
00050   leading significant digits after rounding or truncating is represented
00051   in the declared type of the target. The value is converted to have the
00052   precision and scale of the target. The choice of whether to truncate
00053   or round is implementation-defined.
00054 
00055   [...]
00056 
00057   All numeric values between the smallest and the largest value,
00058   inclusive, in a given exact numeric type have an approximation
00059   obtained by rounding or truncation for that type; it is
00060   implementation-defined which other numeric values have such
00061   approximations.
00062 
00063 5.3 <literal>, page 143
00064 
00065   <exact numeric literal> ::=
00066     <unsigned integer> [ <period> [ <unsigned integer> ] ]
00067   | <period> <unsigned integer>
00068 
00069 6.1 <data type>, page 165:
00070 
00071   19) The <scale> of an <exact numeric type> shall not be greater than
00072       the <precision> of the <exact numeric type>.
00073 
00074   20) For the <exact numeric type>s DECIMAL and NUMERIC:
00075 
00076     a) The maximum value of <precision> is implementation-defined.
00077        <precision> shall not be greater than this value.
00078     b) The maximum value of <scale> is implementation-defined. <scale>
00079        shall not be greater than this maximum value.
00080 
00081   21) NUMERIC specifies the data type exact numeric, with the decimal
00082       precision and scale specified by the <precision> and <scale>.
00083 
00084   22) DECIMAL specifies the data type exact numeric, with the decimal
00085       scale specified by the <scale> and the implementation-defined
00086       decimal precision equal to or greater than the value of the
00087       specified <precision>.
00088 
00089 6.26 <numeric value expression>, page 241:
00090 
00091   1) If the declared type of both operands of a dyadic arithmetic
00092      operator is exact numeric, then the declared type of the result is
00093      an implementation-defined exact numeric type, with precision and
00094      scale determined as follows:
00095 
00096    a) Let S1 and S2 be the scale of the first and second operands
00097       respectively.
00098    b) The precision of the result of addition and subtraction is
00099       implementation-defined, and the scale is the maximum of S1 and S2.
00100    c) The precision of the result of multiplication is
00101       implementation-defined, and the scale is S1 + S2.
00102    d) The precision and scale of the result of division are
00103       implementation-defined.
00104 */
00105 
00106 #include <config.h>
00107 
00108 #include <drizzled/definitions.h>
00109 #include <drizzled/internal/m_string.h>
00110 #include <drizzled/charset_info.h>
00111 #include <drizzled/type/decimal.h>
00112 
00113 #include <plugin/myisam/myisampack.h>
00114 #include <drizzled/util/test.h>
00115 
00116 #ifdef HAVE_ALLOCA_H
00117 #include <alloca.h>
00118 #endif
00119 
00120 #include <algorithm>
00121 #include <time.h>
00122 #include <drizzled/current_session.h>
00123 #include <drizzled/error.h>
00124 #include <drizzled/field.h>
00125 #include <drizzled/internal/my_sys.h>
00126 
00127 using namespace std;
00128 
00129 namespace drizzled
00130 {
00143 int decimal_operation_results(int result)
00144 {
00145   switch (result) {
00146   case E_DEC_OK:
00147     break;
00148   case E_DEC_TRUNCATED:
00149     push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
00150       ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED),
00151       "", (long)-1);
00152     break;
00153   case E_DEC_OVERFLOW:
00154     push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
00155                         ER_TRUNCATED_WRONG_VALUE,
00156                         ER(ER_TRUNCATED_WRONG_VALUE),
00157       "DECIMAL", "");
00158     break;
00159   case E_DEC_DIV_ZERO:
00160     my_error(ER_DIVISION_BY_ZERO, MYF(0));
00161     break;
00162   case E_DEC_BAD_NUM:
00163     push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
00164       ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
00165       ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
00166       "decimal", "", "", (long)-1);
00167     break;
00168   case E_DEC_OOM:
00169     my_error(ER_OUT_OF_RESOURCES, MYF(0));
00170     break;
00171   default:
00172     assert(0);
00173   }
00174   return result;
00175 }
00176 
00177 
00197 int class_decimal2string(const type::Decimal *d,
00198                          uint32_t fixed_dec, String *str)
00199 {
00200   uint32_t mask= E_DEC_FATAL_ERROR;
00201 
00202   /*
00203     Calculate the size of the string: For DECIMAL(a,b), fixed_prec==a
00204     holds true iff the type is also ZEROFILL, which in turn implies
00205     UNSIGNED. Hence the buffer for a ZEROFILLed value is the length
00206     the user requested, plus one for a possible decimal point, plus
00207     one if the user only wanted decimal places, but we force a leading
00208     zero on them. Because the type is implicitly UNSIGNED, we do not
00209     need to reserve a character for the sign. For all other cases,
00210     fixed_prec will be 0, and class_decimal_string_length() will be called
00211     instead to calculate the required size of the buffer.
00212   */
00213   int length= (int)(0
00214                     ? (uint32_t)(((0 == fixed_dec) ? 1 : 0) + 1)
00215                     : (uint32_t)d->string_length());
00216   int result;
00217   if (str->alloc(length))
00218     return check_result(mask, E_DEC_OOM);
00219 
00220   result= decimal2string((decimal_t*) d, (char*) str->ptr(),
00221                          &length, (int)0, fixed_dec,
00222                          '0');
00223   str->length(length);
00224   return check_result(mask, result);
00225 }
00226 
00227 
00247 namespace type {
00248 
00249 int Decimal::val_binary(uint32_t mask, unsigned char *bin, int prec, int scale) const
00250 {
00251   int err1= E_DEC_OK, err2;
00252   type::Decimal rounded;
00253   class_decimal2decimal(this, &rounded);
00254   rounded.frac= decimal_actual_fraction(&rounded);
00255   if (scale < rounded.frac)
00256   {
00257     err1= E_DEC_TRUNCATED;
00258     /* decimal_round can return only E_DEC_TRUNCATED */
00259     decimal_round(&rounded, &rounded, scale, HALF_UP);
00260   }
00261   err2= decimal2bin(&rounded, bin, prec, scale);
00262   if (!err2)
00263     err2= err1;
00264   return check_result(mask, err2);
00265 }
00266 
00267 } // namespace type
00268 
00269 
00286 int type::Decimal::store(uint32_t mask, const char *from, uint32_t length, const CHARSET_INFO * charset)
00287 {
00288   char *end, *from_end;
00289   int err;
00290   char buff[STRING_BUFFER_USUAL_SIZE];
00291   String tmp(buff, sizeof(buff), &my_charset_bin);
00292   if (charset->mbminlen > 1)
00293   {
00294     size_t dummy_errors;
00295     tmp.copy(from, length, charset, &my_charset_utf8_general_ci, &dummy_errors);
00296     from= tmp.ptr();
00297     length=  tmp.length();
00298     charset= &my_charset_bin;
00299   }
00300   from_end= end= (char*) from+length;
00301   err= string2decimal((char *)from, (decimal_t*) this, &end);
00302   if (end != from_end && !err)
00303   {
00304     /* Give warning if there is something other than end space */
00305     for ( ; end < from_end; end++)
00306     {
00307       if (!my_isspace(&my_charset_utf8_general_ci, *end))
00308       {
00309         err= E_DEC_TRUNCATED;
00310         break;
00311       }
00312     }
00313   }
00314   check_result_and_overflow(mask, err);
00315   return err;
00316 }
00317 
00318 void type::Decimal::convert(double &result) const
00319 {
00320   decimal2double(static_cast<const decimal_t*>(this), &result);
00321 }
00322 
00323 type::Decimal *date2_class_decimal(type::Time *ltime, type::Decimal *dec)
00324 {
00325   int64_t date;
00326   date = (ltime->year*100L + ltime->month)*100L + ltime->day;
00327   if (ltime->time_type > type::DRIZZLE_TIMESTAMP_DATE)
00328     date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second;
00329 
00330   if (int2_class_decimal(E_DEC_FATAL_ERROR, date, false, dec))
00331     return dec;
00332 
00333   if (ltime->second_part)
00334   {
00335     dec->buf[(dec->intg-1) / 9 + 1]= ltime->second_part * 1000;
00336     dec->frac= 6;
00337   }
00338 
00339   return dec;
00340 }
00341 
00342 
00343 void class_decimal_trim(uint32_t *precision, uint32_t *scale)
00344 {
00345   if (!(*precision) && !(*scale))
00346   {
00347     *precision= 10;
00348     *scale= 0;
00349     return;
00350   }
00351 }
00352 
00353 
00354 /*
00355   Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
00356   So one variable of type decimal_digit_t is limited:
00357 
00358       0 < decimal_digit <= DIG_MAX < DIG_BASE
00359 
00360   in the struct st_decimal_t:
00361 
00362     intg is the number of *decimal* digits (NOT number of decimal_digit_t's !)
00363          before the point
00364     frac - number of decimal digits after the point
00365     buf is an array of decimal_digit_t's
00366     len is the length of buf (length of allocated space) in decimal_digit_t's,
00367         not in bytes
00368 */
00369 typedef decimal_digit_t dec1;
00370 typedef int64_t      dec2;
00371 
00372 #define DIG_PER_DEC1 9
00373 #define DIG_MASK     100000000
00374 #define DIG_BASE     1000000000
00375 #define DIG_MAX      (DIG_BASE-1)
00376 
00377 template<typename T> 
00378 inline static T round_up(const T &x)
00379 {
00380   return (x+DIG_PER_DEC1-1)/DIG_PER_DEC1;
00381 }
00382 
00383 static const dec1 powers10[DIG_PER_DEC1+1]={
00384   1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
00385 static const int dig2bytes[DIG_PER_DEC1+1]={0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
00386 static const dec1 frac_max[DIG_PER_DEC1-1]={
00387   900000000, 990000000, 999000000,
00388   999900000, 999990000, 999999000,
00389   999999900, 999999990 };
00390 
00391 #ifdef HAVE_VALGRIND
00392 #define sanity(d) assert((d)->len > 0)
00393 #else
00394 #define sanity(d) assert((d)->len >0 && ((d)->buf[0] | \
00395                               (d)->buf[(d)->len-1] | 1))
00396 #endif
00397 
00398 inline static void fix_intg_frac_error(const int len, int &intg1, int &frac1, int &error)
00399 {
00400   if (unlikely(intg1+frac1 > len))
00401   {
00402     if (unlikely(intg1 > len))
00403     {
00404       intg1=(len);
00405       frac1=0;
00406       error=E_DEC_OVERFLOW;
00407     }
00408     else
00409     {
00410       frac1=(len)-intg1;
00411       error=E_DEC_TRUNCATED;
00412     }
00413   }
00414   else
00415     error=E_DEC_OK;
00416 }
00417 
00418 /* assume carry <= 1 */
00419 inline static void add(dec1 &to, const dec1 &from1, const dec1& from2, dec1 &carry)
00420 {
00421   dec1 a=from1+from2+carry;
00422   assert(carry <= 1);
00423   if ((carry= (a >= DIG_BASE))) /* no division here! */
00424     a-=DIG_BASE;
00425   to=a;
00426 }
00427 
00428 inline static void add2(dec1 &to, const dec1 &from1, const dec1 &from2, dec1 &carry)
00429 {
00430   dec2 a=dec2(from1)+from2+carry;
00431   if ((carry= (a >= DIG_BASE)))
00432     a-=DIG_BASE;
00433   if (unlikely(a >= DIG_BASE))
00434   {
00435     a-=DIG_BASE;
00436     carry++;
00437   }
00438   to=dec1(a);
00439 }
00440 
00441 /* to=from1-from2 */
00442 inline static void sub(dec1 &to, const dec1 &from1, const dec1 &from2, dec1 &carry)
00443 {
00444   dec1 a=from1-from2-carry;
00445   if ((carry= (a < 0)))
00446     a+=DIG_BASE;
00447   to=a;
00448 }
00449 
00450 /* to=from1-from2 */
00451 inline static void sub2(dec1 &to, const dec1 &from1, const dec1 &from2, dec1 &carry)
00452 {
00453   dec1 a=from1-from2-carry;
00454   if ((carry= (a < 0)))
00455     a+=DIG_BASE;
00456   if (unlikely(a < 0))
00457   {
00458     a+=DIG_BASE;
00459     carry++;
00460   }
00461   to=a;
00462 }
00463 
00472 void max_decimal(int precision, int frac, decimal_t *to)
00473 {
00474   int intpart;
00475   dec1 *buf= to->buf;
00476   assert(precision && precision >= frac);
00477 
00478   to->sign= 0;
00479   if ((intpart= to->intg= (precision - frac)))
00480   {
00481     const int firstdigits= intpart % DIG_PER_DEC1;
00482     if (firstdigits)
00483       *buf++= powers10[firstdigits] - 1; /* get 9 99 999 ... */
00484     for(intpart/= DIG_PER_DEC1; intpart; intpart--)
00485       *buf++= DIG_MAX;
00486   }
00487 
00488   if ((to->frac= frac))
00489   {
00490     const int lastdigits= frac % DIG_PER_DEC1;
00491     for(frac/= DIG_PER_DEC1; frac; frac--)
00492       *buf++= DIG_MAX;
00493     if (lastdigits)
00494       *buf= frac_max[lastdigits - 1];
00495   }
00496 }
00497 
00498 
00499 static dec1 *remove_leading_zeroes(const decimal_t *from, int *intg_result)
00500 {
00501   int intg= from->intg, i;
00502   dec1 *buf0= from->buf;
00503   i= ((intg - 1) % DIG_PER_DEC1) + 1;
00504   while (intg > 0 && *buf0 == 0)
00505   {
00506     intg-= i;
00507     i= DIG_PER_DEC1;
00508     buf0++;
00509   }
00510   if (intg > 0)
00511   {
00512     for (i= (intg - 1) % DIG_PER_DEC1; *buf0 < powers10[i--]; intg--) ;
00513     assert(intg > 0);
00514   }
00515   else
00516     intg=0;
00517   *intg_result= intg;
00518   return buf0;
00519 }
00520 
00521 
00528 int decimal_actual_fraction(decimal_t *from)
00529 {
00530   int frac= from->frac, i;
00531   dec1 *buf0= from->buf + round_up(from->intg) + round_up(frac) - 1;
00532 
00533   if (frac == 0)
00534     return 0;
00535 
00536   i= ((frac - 1) % DIG_PER_DEC1 + 1);
00537   while (frac > 0 && *buf0 == 0)
00538   {
00539     frac-= i;
00540     i= DIG_PER_DEC1;
00541     buf0--;
00542   }
00543   if (frac > 0)
00544   {
00545     for (i= DIG_PER_DEC1 - ((frac - 1) % DIG_PER_DEC1); *buf0 % powers10[i++] == 0; frac--) {};
00546   }
00547   return frac;
00548 }
00549 
00550 
00572 int decimal2string(const decimal_t *from, char *to, int *to_len,
00573                    int fixed_precision, int fixed_decimals,
00574                    char filler)
00575 {
00576   int len, intg, frac= from->frac, i, intg_len, frac_len, fill;
00577   /* number digits before decimal point */
00578   int fixed_intg= (fixed_precision ?
00579                    (fixed_precision - fixed_decimals) : 0);
00580   int error=E_DEC_OK;
00581   char *s=to;
00582   dec1 *buf, *buf0=from->buf, tmp;
00583 
00584   assert(*to_len >= 2+from->sign);
00585 
00586   /* removing leading zeroes */
00587   buf0= remove_leading_zeroes(from, &intg);
00588   if (unlikely(intg+frac==0))
00589   {
00590     intg=1;
00591     tmp=0;
00592     buf0=&tmp;
00593   }
00594 
00595   if (!(intg_len= fixed_precision ? fixed_intg : intg))
00596     intg_len= 1;
00597   frac_len= fixed_precision ? fixed_decimals : frac;
00598   len= from->sign + intg_len + test(frac) + frac_len;
00599   if (fixed_precision)
00600   {
00601     if (frac > fixed_decimals)
00602     {
00603       error= E_DEC_TRUNCATED;
00604       frac= fixed_decimals;
00605     }
00606     if (intg > fixed_intg)
00607     {
00608       error= E_DEC_OVERFLOW;
00609       intg= fixed_intg;
00610     }
00611   }
00612   else if (unlikely(len > --*to_len)) /* reserve one byte for \0 */
00613   {
00614     int j= len-*to_len;
00615     error= (frac && j <= frac + 1) ? E_DEC_TRUNCATED : E_DEC_OVERFLOW;
00616     if (frac && j >= frac + 1) j--;
00617     if (j > frac)
00618     {
00619       intg-= j-frac;
00620       frac= 0;
00621     }
00622     else
00623       frac-=j;
00624     len= from->sign + intg_len + test(frac) + frac_len;
00625   }
00626   *to_len=len;
00627   s[len]=0;
00628 
00629   if (from->sign)
00630     *s++='-';
00631 
00632   if (frac)
00633   {
00634     char *s1= s + intg_len;
00635     fill= frac_len - frac;
00636     buf=buf0+round_up(intg);
00637     *s1++='.';
00638     for (; frac>0; frac-=DIG_PER_DEC1)
00639     {
00640       dec1 x=*buf++;
00641       for (i=min(frac, DIG_PER_DEC1); i; i--)
00642       {
00643         dec1 y=x/DIG_MASK;
00644         *s1++='0'+(unsigned char)y;
00645         x-=y*DIG_MASK;
00646         x*=10;
00647       }
00648     }
00649     for(; fill; fill--)
00650       *s1++=filler;
00651   }
00652 
00653   fill= intg_len - intg;
00654   if (intg == 0)
00655     fill--; /* symbol 0 before digital point */
00656   for(; fill; fill--)
00657     *s++=filler;
00658   if (intg)
00659   {
00660     s+=intg;
00661     for (buf=buf0+round_up(intg); intg>0; intg-=DIG_PER_DEC1)
00662     {
00663       dec1 x=*--buf;
00664       for (i=min(intg, DIG_PER_DEC1); i; i--)
00665       {
00666         dec1 y=x/10;
00667         *--s='0'+(unsigned char)(x-y*10);
00668         x=y;
00669       }
00670     }
00671   }
00672   else
00673     *s= '0';
00674   return error;
00675 }
00676 
00677 
00687 static void digits_bounds(decimal_t *from, int *start_result, int *end_result)
00688 {
00689   int start, stop, i;
00690   dec1 *buf_beg= from->buf;
00691   dec1 *end= from->buf + round_up(from->intg) + round_up(from->frac);
00692   dec1 *buf_end= end - 1;
00693 
00694   /* find non-zero digit from number begining */
00695   while (buf_beg < end && *buf_beg == 0)
00696     buf_beg++;
00697 
00698   if (buf_beg >= end)
00699   {
00700     /* it is zero */
00701     *start_result= *end_result= 0;
00702     return;
00703   }
00704 
00705   /* find non-zero decimal digit from number begining */
00706   if (buf_beg == from->buf && from->intg)
00707   {
00708     start= DIG_PER_DEC1 - (i= ((from->intg-1) % DIG_PER_DEC1 + 1));
00709     i--;
00710   }
00711   else
00712   {
00713     i= DIG_PER_DEC1 - 1;
00714     start= (int) ((buf_beg - from->buf) * DIG_PER_DEC1);
00715   }
00716   if (buf_beg < end)
00717     for (; *buf_beg < powers10[i--]; start++) ;
00718   *start_result= start; /* index of first decimal digit (from 0) */
00719 
00720   /* find non-zero digit at the end */
00721   while (buf_end > buf_beg  && *buf_end == 0)
00722     buf_end--;
00723   /* find non-zero decimal digit from the end */
00724   if (buf_end == end - 1 && from->frac)
00725   {
00726     stop= (int) (((buf_end - from->buf) * DIG_PER_DEC1 +
00727            (i= ((from->frac - 1) % DIG_PER_DEC1 + 1))));
00728     i= DIG_PER_DEC1 - i + 1;
00729   }
00730   else
00731   {
00732     stop= (int) ((buf_end - from->buf + 1) * DIG_PER_DEC1);
00733     i= 1;
00734   }
00735   for (; *buf_end % powers10[i++] == 0; stop--) {};
00736   *end_result= stop; /* index of position after last decimal digit (from 0) */
00737 }
00738 
00739 
00755 static void do_mini_left_shift(decimal_t *dec, int shift, int beg, int last)
00756 {
00757   dec1 *from= dec->buf + round_up(beg + 1) - 1;
00758   dec1 *end= dec->buf + round_up(last) - 1;
00759   int c_shift= DIG_PER_DEC1 - shift;
00760   assert(from >= dec->buf);
00761   assert(end < dec->buf + dec->len);
00762   if (beg % DIG_PER_DEC1 < shift)
00763     *(from - 1)= (*from) / powers10[c_shift];
00764   for(; from < end; from++)
00765     *from= ((*from % powers10[c_shift]) * powers10[shift] +
00766             (*(from + 1)) / powers10[c_shift]);
00767   *from= (*from % powers10[c_shift]) * powers10[shift];
00768 }
00769 
00770 
00783 static void do_mini_right_shift(decimal_t *dec, int shift, int beg, int last)
00784 {
00785   dec1 *from= dec->buf + round_up(last) - 1;
00786   dec1 *end= dec->buf + round_up(beg + 1) - 1;
00787   int c_shift= DIG_PER_DEC1 - shift;
00788   assert(from < dec->buf + dec->len);
00789   assert(end >= dec->buf);
00790   if (DIG_PER_DEC1 - ((last - 1) % DIG_PER_DEC1 + 1) < shift)
00791     *(from + 1)= (*from % powers10[shift]) * powers10[c_shift];
00792   for(; from > end; from--)
00793     *from= (*from / powers10[shift] +
00794             (*(from - 1) % powers10[shift]) * powers10[c_shift]);
00795   *from= *from / powers10[shift];
00796 }
00797 
00798 
00815 static int decimal_shift(decimal_t *dec, int shift)
00816 {
00817   /* index of first non zero digit (all indexes from 0) */
00818   int beg;
00819   /* index of position after last decimal digit */
00820   int end;
00821   /* index of digit position just after point */
00822   int point= round_up(dec->intg) * DIG_PER_DEC1;
00823   /* new point position */
00824   int new_point= point + shift;
00825   /* number of digits in result */
00826   int digits_int, digits_frac;
00827   /* length of result and new fraction in big digits*/
00828   int new_len, new_frac_len;
00829   /* return code */
00830   int err= E_DEC_OK;
00831   int new_front;
00832 
00833   if (shift == 0)
00834     return E_DEC_OK;
00835 
00836   digits_bounds(dec, &beg, &end);
00837 
00838   if (beg == end)
00839   {
00840     dec->set_zero();
00841     return E_DEC_OK;
00842   }
00843 
00844   digits_int= new_point - beg;
00845   set_if_bigger(digits_int, 0);
00846   digits_frac= end - new_point;
00847   set_if_bigger(digits_frac, 0);
00848 
00849   if ((new_len= round_up(digits_int) + (new_frac_len= round_up(digits_frac))) >
00850       dec->len)
00851   {
00852     int lack= new_len - dec->len;
00853     int diff;
00854 
00855     if (new_frac_len < lack)
00856       return E_DEC_OVERFLOW; /* lack more then we have in fraction */
00857 
00858     /* cat off fraction part to allow new number to fit in our buffer */
00859     err= E_DEC_TRUNCATED;
00860     new_frac_len-= lack;
00861     diff= digits_frac - (new_frac_len * DIG_PER_DEC1);
00862     /* Make rounding method as parameter? */
00863     decimal_round(dec, dec, end - point - diff, HALF_UP);
00864     end-= diff;
00865     digits_frac= new_frac_len * DIG_PER_DEC1;
00866 
00867     if (end <= beg)
00868     {
00869       /*
00870         we lost all digits (they will be shifted out of buffer), so we can
00871         just return 0
00872       */
00873       dec->set_zero();
00874 
00875       return E_DEC_TRUNCATED;
00876     }
00877   }
00878 
00879   if (shift % DIG_PER_DEC1)
00880   {
00881     int l_mini_shift, r_mini_shift, mini_shift;
00882     int do_left;
00883     /*
00884       Calculate left/right shift to align decimal digits inside our bug
00885       digits correctly
00886     */
00887     if (shift > 0)
00888     {
00889       l_mini_shift= shift % DIG_PER_DEC1;
00890       r_mini_shift= DIG_PER_DEC1 - l_mini_shift;
00891       /*
00892         It is left shift so prefer left shift, but if we have not place from
00893         left, we have to have it from right, because we checked length of
00894         result
00895       */
00896       do_left= l_mini_shift <= beg;
00897       assert(do_left || (dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
00898     }
00899     else
00900     {
00901       r_mini_shift= (-shift) % DIG_PER_DEC1;
00902       l_mini_shift= DIG_PER_DEC1 - r_mini_shift;
00903       /* see comment above */
00904       do_left= !((dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
00905       assert(!do_left || l_mini_shift <= beg);
00906     }
00907     if (do_left)
00908     {
00909       do_mini_left_shift(dec, l_mini_shift, beg, end);
00910       mini_shift= (-l_mini_shift);
00911     }
00912     else
00913     {
00914       do_mini_right_shift(dec, r_mini_shift, beg, end);
00915       mini_shift= r_mini_shift;
00916     }
00917     new_point+= mini_shift;
00918     /*
00919       If number is shifted and correctly aligned in buffer we can
00920       finish
00921     */
00922     if (!(shift+= mini_shift) && (new_point - digits_int) < DIG_PER_DEC1)
00923     {
00924       dec->intg= digits_int;
00925       dec->frac= digits_frac;
00926       return err;                 /* already shifted as it should be */
00927     }
00928     beg+= mini_shift;
00929     end+= mini_shift;
00930   }
00931 
00932   /* if new 'decimal front' is in first digit, we do not need move digits */
00933   if ((new_front= (new_point - digits_int)) >= DIG_PER_DEC1 ||
00934       new_front < 0)
00935   {
00936     /* need to move digits */
00937     int d_shift;
00938     dec1 *to, *barier;
00939     if (new_front > 0)
00940     {
00941       /* move left */
00942       d_shift= new_front / DIG_PER_DEC1;
00943       to= dec->buf + (round_up(beg + 1) - 1 - d_shift);
00944       barier= dec->buf + (round_up(end) - 1 - d_shift);
00945       assert(to >= dec->buf);
00946       assert(barier + d_shift < dec->buf + dec->len);
00947       for(; to <= barier; to++)
00948         *to= *(to + d_shift);
00949       for(barier+= d_shift; to <= barier; to++)
00950         *to= 0;
00951       d_shift= -d_shift;
00952     }
00953     else
00954     {
00955       /* move right */
00956       d_shift= (1 - new_front) / DIG_PER_DEC1;
00957       to= dec->buf + round_up(end) - 1 + d_shift;
00958       barier= dec->buf + round_up(beg + 1) - 1 + d_shift;
00959       assert(to < dec->buf + dec->len);
00960       assert(barier - d_shift >= dec->buf);
00961       for(; to >= barier; to--)
00962         *to= *(to - d_shift);
00963       for(barier-= d_shift; to >= barier; to--)
00964         *to= 0;
00965     }
00966     d_shift*= DIG_PER_DEC1;
00967     beg+= d_shift;
00968     end+= d_shift;
00969     new_point+= d_shift;
00970   }
00971 
00972   /*
00973     If there are gaps then fill ren with 0.
00974 
00975     Only one of following 'for' loops will work becouse beg <= end
00976   */
00977   beg= round_up(beg + 1) - 1;
00978   end= round_up(end) - 1;
00979   assert(new_point >= 0);
00980 
00981   /* We don't want negative new_point below */
00982   if (new_point != 0)
00983     new_point= round_up(new_point) - 1;
00984 
00985   if (new_point > end)
00986   {
00987     do
00988     {
00989       dec->buf[new_point]=0;
00990     } while (--new_point > end);
00991   }
00992   else
00993   {
00994     for (; new_point < beg; new_point++)
00995       dec->buf[new_point]= 0;
00996   }
00997   dec->intg= digits_int;
00998   dec->frac= digits_frac;
00999   return err;
01000 }
01001 
01002 
01022 int
01023 internal_str2dec(char *from, decimal_t *to, char **end, bool fixed)
01024 {
01025   char *s= from, *s1;
01026   char *end_of_string = *end;
01027   char *endp;
01028   int i, intg, frac, error, intg1, frac1;
01029   dec1 x,*buf;
01030   sanity(to);
01031 
01032   error= E_DEC_BAD_NUM;                         /* In case of bad number */
01033   while (s < end_of_string && my_isspace(&my_charset_utf8_general_ci, *s))
01034     s++;
01035   if (s == end_of_string)
01036     goto fatal_error;
01037 
01038   if ((to->sign= (*s == '-')))
01039     s++;
01040   else if (*s == '+')
01041     s++;
01042 
01043   s1=s;
01044   while (s < end_of_string && my_isdigit(&my_charset_utf8_general_ci, *s))
01045     s++;
01046   intg= (int) (s-s1);
01047   if (s < end_of_string && *s=='.')
01048   {
01049     endp= s+1;
01050     while (endp < end_of_string && my_isdigit(&my_charset_utf8_general_ci, *endp))
01051       endp++;
01052     frac= (int) (endp - s - 1);
01053   }
01054   else
01055   {
01056     frac= 0;
01057     endp= s;
01058   }
01059 
01060   *end= endp;
01061 
01062   if (frac+intg == 0)
01063     goto fatal_error;
01064 
01065   error= 0;
01066   if (fixed)
01067   {
01068     if (frac > to->frac)
01069     {
01070       error=E_DEC_TRUNCATED;
01071       frac=to->frac;
01072     }
01073     if (intg > to->intg)
01074     {
01075       error=E_DEC_OVERFLOW;
01076       intg=to->intg;
01077     }
01078     intg1=round_up(intg);
01079     frac1=round_up(frac);
01080     if (intg1+frac1 > to->len)
01081     {
01082       error= E_DEC_OOM;
01083       goto fatal_error;
01084     }
01085   }
01086   else
01087   {
01088     intg1=round_up(intg);
01089     frac1=round_up(frac);
01090     fix_intg_frac_error(to->len, intg1, frac1, error);
01091     if (unlikely(error))
01092     {
01093       frac=frac1*DIG_PER_DEC1;
01094       if (error == E_DEC_OVERFLOW)
01095         intg=intg1*DIG_PER_DEC1;
01096     }
01097   }
01098   /* Error is guranteed to be set here */
01099   to->intg=intg;
01100   to->frac=frac;
01101 
01102   buf=to->buf+intg1;
01103   s1=s;
01104 
01105   for (x=0, i=0; intg; intg--)
01106   {
01107     x+= (*--s - '0')*powers10[i];
01108 
01109     if (unlikely(++i == DIG_PER_DEC1))
01110     {
01111       *--buf=x;
01112       x=0;
01113       i=0;
01114     }
01115   }
01116   if (i)
01117     *--buf=x;
01118 
01119   buf=to->buf+intg1;
01120   for (x=0, i=0; frac; frac--)
01121   {
01122     x= (*++s1 - '0') + x*10;
01123 
01124     if (unlikely(++i == DIG_PER_DEC1))
01125     {
01126       *buf++=x;
01127       x=0;
01128       i=0;
01129     }
01130   }
01131   if (i)
01132     *buf=x*powers10[DIG_PER_DEC1-i];
01133 
01134   /* Handle exponent */
01135   if (endp+1 < end_of_string && (*endp == 'e' || *endp == 'E'))
01136   {
01137     int str_error;
01138     const int64_t exponent= internal::my_strtoll10(endp+1, (char**) &end_of_string,
01139                                                    &str_error);
01140 
01141     if (end_of_string != endp +1)               /* If at least one digit */
01142     {
01143       *end= (char*) end_of_string;
01144       if (str_error > 0)
01145       {
01146         error= E_DEC_BAD_NUM;
01147         goto fatal_error;
01148       }
01149       if (exponent > INT_MAX/2 || (str_error == 0 && exponent < 0))
01150       {
01151         error= E_DEC_OVERFLOW;
01152         goto fatal_error;
01153       }
01154       if (exponent < INT_MIN/2 && error != E_DEC_OVERFLOW)
01155       {
01156         error= E_DEC_TRUNCATED;
01157         goto fatal_error;
01158       }
01159       if (error != E_DEC_OVERFLOW)
01160         error= decimal_shift(to, (int) exponent);
01161     }
01162   }
01163   return error;
01164 
01165 fatal_error:
01166   to->set_zero();
01167   return error;
01168 }
01169 
01170 
01181 int decimal2double(const decimal_t *from, double *to)
01182 {
01183   char strbuf[FLOATING_POINT_BUFFER], *end;
01184   int len= sizeof(strbuf);
01185   int rc, error;
01186 
01187   rc = decimal2string(from, strbuf, &len, 0, 0, 0);
01188   end= strbuf + len;
01189 
01190   *to= internal::my_strtod(strbuf, &end, &error);
01191 
01192   return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
01193 }
01194 
01205 int double2decimal(const double from, decimal_t *to)
01206 {
01207   char buff[FLOATING_POINT_BUFFER], *end;
01208   int res;
01209   end= buff + internal::my_gcvt(from,
01210                                 internal::MY_GCVT_ARG_DOUBLE,
01211                                 sizeof(buff) - 1, buff, NULL);
01212   res= string2decimal(buff, to, &end);
01213   return(res);
01214 }
01215 
01216 
01217 static int ull2dec(uint64_t from, decimal_t *to)
01218 {
01219   int intg1, error=E_DEC_OK;
01220   uint64_t x=from;
01221   dec1 *buf;
01222 
01223   sanity(to);
01224 
01225   for (intg1=1; from >= DIG_BASE; intg1++, from/=DIG_BASE) {};
01226   if (unlikely(intg1 > to->len))
01227   {
01228     intg1=to->len;
01229     error=E_DEC_OVERFLOW;
01230   }
01231   to->frac=0;
01232   to->intg=intg1*DIG_PER_DEC1;
01233 
01234   for (buf=to->buf+intg1; intg1; intg1--)
01235   {
01236     uint64_t y=x/DIG_BASE;
01237     *--buf=(dec1)(x-y*DIG_BASE);
01238     x=y;
01239   }
01240   return error;
01241 }
01242 
01243 int uint64_t2decimal(const uint64_t from, decimal_t *to)
01244 {
01245   to->sign=0;
01246   return ull2dec(from, to);
01247 }
01248 
01249 int int64_t2decimal(const int64_t from, decimal_t *to)
01250 {
01251   if ((to->sign= from < 0))
01252     return ull2dec(-from, to);
01253   return ull2dec(from, to);
01254 }
01255 
01256 int decimal2uint64_t(const decimal_t *from, uint64_t *to)
01257 {
01258   dec1 *buf=from->buf;
01259   uint64_t x=0;
01260   int intg, frac;
01261 
01262   if (from->sign)
01263   {
01264       *to= 0ULL;
01265       return E_DEC_OVERFLOW;
01266   }
01267 
01268   for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
01269   {
01270     uint64_t y=x;
01271     x=x*DIG_BASE + *buf++;
01272     if (unlikely(y > ((uint64_t) UINT64_MAX/DIG_BASE) || x < y))
01273     {
01274       *to=UINT64_MAX;
01275       return E_DEC_OVERFLOW;
01276     }
01277   }
01278   *to=x;
01279   for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
01280     if (*buf++)
01281       return E_DEC_TRUNCATED;
01282   return E_DEC_OK;
01283 }
01284 
01285 int decimal2int64_t(const decimal_t *from, int64_t *to)
01286 {
01287   dec1 *buf=from->buf;
01288   int64_t x=0;
01289   int intg, frac;
01290 
01291   for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
01292   {
01293     int64_t y=x;
01294     /*
01295       Attention: trick!
01296       we're calculating -|from| instead of |from| here
01297       because |INT64_MIN| > INT64_MAX
01298       so we can convert -9223372036854775808 correctly
01299     */
01300     x=x*DIG_BASE - *buf++;
01301     if (unlikely(y < (INT64_MIN/DIG_BASE) || x > y))
01302     {
01303       /*
01304         the decimal is bigger than any possible integer
01305         return border integer depending on the sign
01306       */
01307       *to= from->sign ? INT64_MIN : INT64_MAX;
01308       return E_DEC_OVERFLOW;
01309     }
01310   }
01311   /* boundary case: 9223372036854775808 */
01312   if (unlikely(from->sign==0 && x == INT64_MIN))
01313   {
01314     *to= INT64_MAX;
01315     return E_DEC_OVERFLOW;
01316   }
01317 
01318   *to=from->sign ? x : -x;
01319   for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
01320     if (*buf++)
01321       return E_DEC_TRUNCATED;
01322   return E_DEC_OK;
01323 }
01324 
01404 int decimal2bin(const decimal_t *from, unsigned char *to, int precision, int frac)
01405 {
01406   dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
01407   int error=E_DEC_OK, intg=precision-frac,
01408       isize1, intg1, intg1x, from_intg,
01409       intg0=intg/DIG_PER_DEC1,
01410       frac0=frac/DIG_PER_DEC1,
01411       intg0x=intg-intg0*DIG_PER_DEC1,
01412       frac0x=frac-frac0*DIG_PER_DEC1,
01413       frac1=from->frac/DIG_PER_DEC1,
01414       frac1x=from->frac-frac1*DIG_PER_DEC1,
01415       isize0=intg0*sizeof(dec1)+dig2bytes[intg0x],
01416       fsize0=frac0*sizeof(dec1)+dig2bytes[frac0x],
01417       fsize1=frac1*sizeof(dec1)+dig2bytes[frac1x];
01418   const int orig_isize0= isize0;
01419   const int orig_fsize0= fsize0;
01420   unsigned char *orig_to= to;
01421 
01422   buf1= remove_leading_zeroes(from, &from_intg);
01423 
01424   if (unlikely(from_intg+fsize1==0))
01425   {
01426     mask=0; /* just in case */
01427     intg=1;
01428     buf1=&mask;
01429   }
01430 
01431   intg1=from_intg/DIG_PER_DEC1;
01432   intg1x=from_intg-intg1*DIG_PER_DEC1;
01433   isize1=intg1*sizeof(dec1)+dig2bytes[intg1x];
01434 
01435   if (intg < from_intg)
01436   {
01437     buf1+=intg1-intg0+(intg1x>0)-(intg0x>0);
01438     intg1=intg0; intg1x=intg0x;
01439     error=E_DEC_OVERFLOW;
01440   }
01441   else if (isize0 > isize1)
01442   {
01443     while (isize0-- > isize1)
01444       *to++= (char)mask;
01445   }
01446   if (fsize0 < fsize1)
01447   {
01448     frac1=frac0; frac1x=frac0x;
01449     error=E_DEC_TRUNCATED;
01450   }
01451   else if (fsize0 > fsize1 && frac1x)
01452   {
01453     if (frac0 == frac1)
01454     {
01455       frac1x=frac0x;
01456       fsize0= fsize1;
01457     }
01458     else
01459     {
01460       frac1++;
01461       frac1x=0;
01462     }
01463   }
01464 
01465   /* intg1x part */
01466   if (intg1x)
01467   {
01468     int i=dig2bytes[intg1x];
01469     dec1 x=(*buf1++ % powers10[intg1x]) ^ mask;
01470     switch (i)
01471     {
01472       case 1: mi_int1store(to, x); break;
01473       case 2: mi_int2store(to, x); break;
01474       case 3: mi_int3store(to, x); break;
01475       case 4: mi_int4store(to, x); break;
01476       default: assert(0);
01477     }
01478     to+=i;
01479   }
01480 
01481   /* intg1+frac1 part */
01482   for (stop1=buf1+intg1+frac1; buf1 < stop1; to+=sizeof(dec1))
01483   {
01484     dec1 x=*buf1++ ^ mask;
01485     assert(sizeof(dec1) == 4);
01486     mi_int4store(to, x);
01487   }
01488 
01489   /* frac1x part */
01490   if (frac1x)
01491   {
01492     dec1 x;
01493     int i=dig2bytes[frac1x],
01494         lim=(frac1 < frac0 ? DIG_PER_DEC1 : frac0x);
01495     while (frac1x < lim && dig2bytes[frac1x] == i)
01496       frac1x++;
01497     x=(*buf1 / powers10[DIG_PER_DEC1 - frac1x]) ^ mask;
01498     switch (i)
01499     {
01500       case 1: mi_int1store(to, x); break;
01501       case 2: mi_int2store(to, x); break;
01502       case 3: mi_int3store(to, x); break;
01503       case 4: mi_int4store(to, x); break;
01504       default: assert(0);
01505     }
01506     to+=i;
01507   }
01508   if (fsize0 > fsize1)
01509   {
01510     unsigned char *to_end= orig_to + orig_fsize0 + orig_isize0;
01511 
01512     while (fsize0-- > fsize1 && to < to_end)
01513       *to++= (unsigned char)mask;
01514   }
01515   orig_to[0]^= 0x80;
01516 
01517   /* Check that we have written the whole decimal and nothing more */
01518   assert(to == orig_to + orig_fsize0 + orig_isize0);
01519   return error;
01520 }
01521 
01537 int bin2decimal(const unsigned char *from, decimal_t *to, int precision, int scale)
01538 {
01539   int error=E_DEC_OK, intg=precision-scale,
01540       intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
01541       intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1,
01542       intg1=intg0+(intg0x>0), frac1=frac0+(frac0x>0);
01543   dec1 *buf=to->buf, mask=(*from & 0x80) ? 0 : -1;
01544   const unsigned char *stop;
01545   unsigned char *d_copy;
01546   int bin_size= decimal_bin_size(precision, scale);
01547 
01548   sanity(to);
01549   d_copy= (unsigned char*) alloca(bin_size);
01550   memcpy(d_copy, from, bin_size);
01551   d_copy[0]^= 0x80;
01552   from= d_copy;
01553 
01554   fix_intg_frac_error(to->len, intg1, frac1, error);
01555   if (unlikely(error))
01556   {
01557     if (intg1 < intg0+(intg0x>0))
01558     {
01559       from+=dig2bytes[intg0x]+sizeof(dec1)*(intg0-intg1);
01560       frac0=frac0x=intg0x=0;
01561       intg0=intg1;
01562     }
01563     else
01564     {
01565       frac0x=0;
01566       frac0=frac1;
01567     }
01568   }
01569 
01570   to->sign=(mask != 0);
01571   to->intg=intg0*DIG_PER_DEC1+intg0x;
01572   to->frac=frac0*DIG_PER_DEC1+frac0x;
01573 
01574   if (intg0x)
01575   {
01576     int i=dig2bytes[intg0x];
01577     dec1 x= 0;
01578     switch (i)
01579     {
01580       case 1: x=mi_sint1korr(from); break;
01581       case 2: x=mi_sint2korr(from); break;
01582       case 3: x=mi_sint3korr(from); break;
01583       case 4: x=mi_sint4korr(from); break;
01584       default: assert(0);
01585     }
01586     from+=i;
01587     *buf=x ^ mask;
01588     if (((uint64_t)*buf) >= (uint64_t) powers10[intg0x+1])
01589       goto err;
01590     if (buf > to->buf || *buf != 0)
01591       buf++;
01592     else
01593       to->intg-=intg0x;
01594   }
01595   for (stop=from+intg0*sizeof(dec1); from < stop; from+=sizeof(dec1))
01596   {
01597     assert(sizeof(dec1) == 4);
01598     *buf=mi_sint4korr(from) ^ mask;
01599     if (((uint32_t)*buf) > DIG_MAX)
01600       goto err;
01601     if (buf > to->buf || *buf != 0)
01602       buf++;
01603     else
01604       to->intg-=DIG_PER_DEC1;
01605   }
01606   assert(to->intg >=0);
01607   for (stop=from+frac0*sizeof(dec1); from < stop; from+=sizeof(dec1))
01608   {
01609     assert(sizeof(dec1) == 4);
01610     *buf=mi_sint4korr(from) ^ mask;
01611     if (((uint32_t)*buf) > DIG_MAX)
01612       goto err;
01613     buf++;
01614   }
01615   if (frac0x)
01616   {
01617     int i=dig2bytes[frac0x];
01618     dec1 x= 0;
01619     switch (i)
01620     {
01621       case 1: x=mi_sint1korr(from); break;
01622       case 2: x=mi_sint2korr(from); break;
01623       case 3: x=mi_sint3korr(from); break;
01624       case 4: x=mi_sint4korr(from); break;
01625       default: assert(0);
01626     }
01627     *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
01628     if (((uint32_t)*buf) > DIG_MAX)
01629       goto err;
01630     buf++;
01631   }
01632   return error;
01633 
01634 err:
01635   to->set_zero();
01636   return(E_DEC_BAD_NUM);
01637 }
01638 
01644 int decimal_bin_size(int precision, int scale)
01645 {
01646   int intg=precision-scale,
01647       intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
01648       intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1;
01649 
01650   assert(scale >= 0 && precision > 0 && scale <= precision);
01651   return intg0*sizeof(dec1)+dig2bytes[intg0x]+
01652          frac0*sizeof(dec1)+dig2bytes[frac0x];
01653 }
01654 
01670 int
01671 decimal_round(const decimal_t *from, decimal_t *to, int scale,
01672               decimal_round_mode mode)
01673 {
01674   int frac0=scale>0 ? round_up(scale) : scale/DIG_PER_DEC1,
01675       frac1=round_up(from->frac), round_digit= 0,
01676       intg0=round_up(from->intg), error=E_DEC_OK, len=to->len,
01677       intg1=round_up(from->intg +
01678                      (((intg0 + frac0)>0) && (from->buf[0] == DIG_MAX)));
01679   dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
01680   int first_dig;
01681 
01682   sanity(to);
01683 
01684   switch (mode) {
01685   case HALF_UP:
01686   case HALF_EVEN:       round_digit=5; break;
01687   case CEILING:         round_digit= from->sign ? 10 : 0; break;
01688   case FLOOR:           round_digit= from->sign ? 0 : 10; break;
01689   case TRUNCATE:        round_digit=10; break;
01690   default: assert(0);
01691   }
01692 
01693   if (unlikely(frac0+intg0 > len))
01694   {
01695     frac0=len-intg0;
01696     scale=frac0*DIG_PER_DEC1;
01697     error=E_DEC_TRUNCATED;
01698   }
01699 
01700   if (scale+from->intg < 0)
01701   {
01702     to->set_zero();
01703     return E_DEC_OK;
01704   }
01705 
01706   if (to != from || intg1>intg0)
01707   {
01708     dec1 *p0= buf0+intg0+max(frac1, frac0);
01709     dec1 *p1= buf1+intg1+max(frac1, frac0);
01710 
01711     while (buf0 < p0)
01712       *(--p1) = *(--p0);
01713     if (unlikely(intg1 > intg0))
01714       to->buf[0]= 0;
01715 
01716     intg0= intg1;
01717     buf0=to->buf;
01718     buf1=to->buf;
01719     to->sign=from->sign;
01720     to->intg=min(intg0, len)*DIG_PER_DEC1;
01721   }
01722 
01723   if (frac0 > frac1)
01724   {
01725     buf1+=intg0+frac1;
01726     while (frac0-- > frac1)
01727       *buf1++=0;
01728     goto done;
01729   }
01730 
01731   if (scale >= from->frac)
01732     goto done; /* nothing to do */
01733 
01734   buf0+=intg0+frac0-1;
01735   buf1+=intg0+frac0-1;
01736   if (scale == frac0*DIG_PER_DEC1)
01737   {
01738     int do_inc= false;
01739     assert(frac0+intg0 >= 0);
01740     switch (round_digit) {
01741     case 0:
01742     {
01743       dec1 *p0= buf0 + (frac1-frac0);
01744       for (; p0 > buf0; p0--)
01745       {
01746         if (*p0)
01747         {
01748           do_inc= true;
01749           break;
01750         }
01751       }
01752       break;
01753     }
01754     case 5:
01755     {
01756       x= buf0[1]/DIG_MASK;
01757       do_inc= (x>5) || ((x == 5) &&
01758                         (mode == HALF_UP || (frac0+intg0 > 0 && *buf0 & 1)));
01759       break;
01760     }
01761     default:
01762       break;
01763     }
01764     if (do_inc)
01765     {
01766       if (frac0+intg0>0)
01767         (*buf1)++;
01768       else
01769         *(++buf1)=DIG_BASE;
01770     }
01771     else if (frac0+intg0==0)
01772     {
01773       to->set_zero();
01774       return E_DEC_OK;
01775     }
01776   }
01777   else
01778   {
01780     int pos=frac0*DIG_PER_DEC1-scale-1;
01781     assert(frac0+intg0 > 0);
01782     x=*buf1 / powers10[pos];
01783     y=x % 10;
01784     if (y > round_digit ||
01785         (round_digit == 5 && y == 5 && (mode == HALF_UP || (x/10) & 1)))
01786       x+=10;
01787     *buf1=powers10[pos]*(x-y);
01788   }
01789   /*
01790     In case we're rounding e.g. 1.5e9 to 2.0e9, the decimal_digit_t's inside
01791     the buffer are as follows.
01792 
01793     Before <1, 5e8>
01794     After  <2, 5e8>
01795 
01796     Hence we need to set the 2nd field to 0.
01797     The same holds if we round 1.5e-9 to 2e-9.
01798    */
01799   if (frac0 < frac1)
01800   {
01801     dec1 *buf= to->buf + ((scale == 0 && intg0 == 0) ? 1 : intg0 + frac0);
01802     dec1 *end= to->buf + len;
01803 
01804     while (buf < end)
01805       *buf++=0;
01806   }
01807   if (*buf1 >= DIG_BASE)
01808   {
01809     carry=1;
01810     *buf1-=DIG_BASE;
01811     while (carry && --buf1 >= to->buf)
01812       add(*buf1, *buf1, 0, carry);
01813     if (unlikely(carry))
01814     {
01815       /* shifting the number to create space for new digit */
01816       if (frac0+intg0 >= len)
01817       {
01818         frac0--;
01819         scale=frac0*DIG_PER_DEC1;
01820         error=E_DEC_TRUNCATED; /* XXX */
01821       }
01822       for (buf1=to->buf+intg0+max(frac0,0); buf1 > to->buf; buf1--)
01823       {
01824         buf1[0]=buf1[-1];
01825       }
01826       *buf1=1;
01827       to->intg++;
01828     }
01829   }
01830   else
01831   {
01832     for (;;)
01833     {
01834       if (likely(*buf1))
01835         break;
01836       if (buf1-- == to->buf)
01837       {
01838         /* making 'zero' with the proper scale */
01839         dec1 *p0= to->buf + frac0 + 1;
01840         to->intg=1;
01841         to->frac= max(scale, 0);
01842         to->sign= 0;
01843         for (buf1= to->buf; buf1<p0; buf1++)
01844           *buf1= 0;
01845         return E_DEC_OK;
01846       }
01847     }
01848   }
01849 
01850   /* Here we  check 999.9 -> 1000 case when we need to increase intg */
01851   first_dig= to->intg % DIG_PER_DEC1;
01852   if (first_dig && (*buf1 >= powers10[first_dig]))
01853     to->intg++;
01854 
01855   if (scale<0)
01856     scale=0;
01857 
01858 done:
01859   to->frac=scale;
01860   return error;
01861 }
01862 
01863 static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
01864 {
01865   int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
01866       frac1=round_up(from1->frac), frac2=round_up(from2->frac),
01867       frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
01868   dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
01869 
01870   sanity(to);
01871 
01872   /* is there a need for extra word because of carry ? */
01873   x=intg1 > intg2 ? from1->buf[0] :
01874     intg2 > intg1 ? from2->buf[0] :
01875     from1->buf[0] + from2->buf[0] ;
01876   if (unlikely(x > DIG_MAX-1)) /* yes, there is */
01877   {
01878     intg0++;
01879     to->buf[0]=0; /* safety */
01880   }
01881 
01882   fix_intg_frac_error(to->len, intg0, frac0, error);
01883   if (unlikely(error == E_DEC_OVERFLOW))
01884   {
01885     max_decimal(to->len * DIG_PER_DEC1, 0, to);
01886     return error;
01887   }
01888 
01889   buf0=to->buf+intg0+frac0;
01890 
01891   to->sign=from1->sign;
01892   to->frac=max(from1->frac, from2->frac);
01893   to->intg=intg0*DIG_PER_DEC1;
01894   if (unlikely(error))
01895   {
01896     set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
01897     set_if_smaller(frac1, frac0);
01898     set_if_smaller(frac2, frac0);
01899     set_if_smaller(intg1, intg0);
01900     set_if_smaller(intg2, intg0);
01901   }
01902 
01903   /* part 1 - cmax(frac) ... cmin(frac) */
01904   if (frac1 > frac2)
01905   {
01906     buf1=from1->buf+intg1+frac1;
01907     stop=from1->buf+intg1+frac2;
01908     buf2=from2->buf+intg2+frac2;
01909     stop2=from1->buf+(intg1 > intg2 ? intg1-intg2 : 0);
01910   }
01911   else
01912   {
01913     buf1=from2->buf+intg2+frac2;
01914     stop=from2->buf+intg2+frac1;
01915     buf2=from1->buf+intg1+frac1;
01916     stop2=from2->buf+(intg2 > intg1 ? intg2-intg1 : 0);
01917   }
01918   while (buf1 > stop)
01919     *--buf0=*--buf1;
01920 
01921   /* part 2 - cmin(frac) ... cmin(intg) */
01922   carry=0;
01923   while (buf1 > stop2)
01924   {
01925     add(*--buf0, *--buf1, *--buf2, carry);
01926   }
01927 
01928   /* part 3 - cmin(intg) ... cmax(intg) */
01929   buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
01930                         ((stop=from2->buf)+intg2-intg1) ;
01931   while (buf1 > stop)
01932   {
01933     add(*--buf0, *--buf1, 0, carry);
01934   }
01935 
01936   if (unlikely(carry))
01937     *--buf0=1;
01938   assert(buf0 == to->buf || buf0 == to->buf+1);
01939 
01940   return error;
01941 }
01942 
01943 /* to=from1-from2.
01944    if to==0, return -1/0/+1 - the result of the comparison */
01945 static int do_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
01946 {
01947   int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
01948       frac1=round_up(from1->frac), frac2=round_up(from2->frac);
01949   int frac0=max(frac1, frac2), error;
01950   dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
01951 
01952   /* let carry:=1 if from2 > from1 */
01953   start1=buf1=from1->buf; stop1=buf1+intg1;
01954   start2=buf2=from2->buf; stop2=buf2+intg2;
01955   if (unlikely(*buf1 == 0))
01956   {
01957     while (buf1 < stop1 && *buf1 == 0)
01958       buf1++;
01959     start1=buf1;
01960     intg1= (int) (stop1-buf1);
01961   }
01962   if (unlikely(*buf2 == 0))
01963   {
01964     while (buf2 < stop2 && *buf2 == 0)
01965       buf2++;
01966     start2=buf2;
01967     intg2= (int) (stop2-buf2);
01968   }
01969   if (intg2 > intg1)
01970     carry=1;
01971   else if (intg2 == intg1)
01972   {
01973     dec1 *end1= stop1 + (frac1 - 1);
01974     dec1 *end2= stop2 + (frac2 - 1);
01975     while (unlikely((buf1 <= end1) && (*end1 == 0)))
01976       end1--;
01977     while (unlikely((buf2 <= end2) && (*end2 == 0)))
01978       end2--;
01979     frac1= (int) (end1 - stop1) + 1;
01980     frac2= (int) (end2 - stop2) + 1;
01981     while (buf1 <=end1 && buf2 <= end2 && *buf1 == *buf2)
01982       buf1++, buf2++;
01983     if (buf1 <= end1)
01984     {
01985       if (buf2 <= end2)
01986         carry= *buf2 > *buf1;
01987       else
01988         carry= 0;
01989     }
01990     else
01991     {
01992       if (buf2 <= end2)
01993         carry=1;
01994       else /* short-circuit everything: from1 == from2 */
01995       {
01996         if (to == 0) /* decimal_cmp() */
01997           return 0;
01998 
01999         to->set_zero();
02000 
02001         return E_DEC_OK;
02002       }
02003     }
02004   }
02005 
02006   if (to == 0) /* decimal_cmp() */
02007     return carry == from1->sign ? 1 : -1;
02008 
02009   sanity(to);
02010 
02011   to->sign=from1->sign;
02012 
02013   /* ensure that always from1 > from2 (and intg1 >= intg2) */
02014   if (carry)
02015   {
02016     swap(from1, from2);
02017     swap(start1, start2);
02018     swap(intg1, intg2);
02019     swap(frac1, frac2);
02020     to->sign= 1 - to->sign;
02021   }
02022 
02023   fix_intg_frac_error(to->len, intg1, frac0, error);
02024   buf0=to->buf+intg1+frac0;
02025 
02026   to->frac=max(from1->frac, from2->frac);
02027   to->intg=intg1*DIG_PER_DEC1;
02028   if (unlikely(error))
02029   {
02030     set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
02031     set_if_smaller(frac1, frac0);
02032     set_if_smaller(frac2, frac0);
02033     set_if_smaller(intg2, intg1);
02034   }
02035   carry=0;
02036 
02037   /* part 1 - cmax(frac) ... cmin(frac) */
02038   if (frac1 > frac2)
02039   {
02040     buf1=start1+intg1+frac1;
02041     stop1=start1+intg1+frac2;
02042     buf2=start2+intg2+frac2;
02043     while (frac0-- > frac1)
02044       *--buf0=0;
02045     while (buf1 > stop1)
02046       *--buf0=*--buf1;
02047   }
02048   else
02049   {
02050     buf1=start1+intg1+frac1;
02051     buf2=start2+intg2+frac2;
02052     stop2=start2+intg2+frac1;
02053     while (frac0-- > frac2)
02054       *--buf0=0;
02055     while (buf2 > stop2)
02056     {
02057       sub(*--buf0, 0, *--buf2, carry);
02058     }
02059   }
02060 
02061   /* part 2 - cmin(frac) ... intg2 */
02062   while (buf2 > start2)
02063   {
02064     sub(*--buf0, *--buf1, *--buf2, carry);
02065   }
02066 
02067   /* part 3 - intg2 ... intg1 */
02068   while (carry && buf1 > start1)
02069   {
02070     sub(*--buf0, *--buf1, 0, carry);
02071   }
02072 
02073   while (buf1 > start1)
02074     *--buf0=*--buf1;
02075 
02076   while (buf0 > to->buf)
02077     *--buf0=0;
02078 
02079   return error;
02080 }
02081 
02082 int decimal_intg(const decimal_t *from)
02083 {
02084   int res;
02085   dec1 *tmp_res;
02086   tmp_res= remove_leading_zeroes(from, &res);
02087   return res;
02088 }
02089 
02090 int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
02091 {
02092   if (likely(from1->sign == from2->sign))
02093     return do_add(from1, from2, to);
02094   return do_sub(from1, from2, to);
02095 }
02096 
02097 int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
02098 {
02099   if (likely(from1->sign == from2->sign))
02100     return do_sub(from1, from2, to);
02101   return do_add(from1, from2, to);
02102 }
02103 
02104 int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
02105 {
02106   if (likely(from1->sign == from2->sign))
02107     return do_sub(from1, from2, 0);
02108   return from1->sign > from2->sign ? -1 : 1;
02109 }
02110 
02111 int decimal_t::isZero() const
02112 {
02113   dec1 *buf1= buf,
02114        *end= buf1 +round_up(intg) +round_up(frac);
02115 
02116   while (buf1 < end)
02117   {
02118     if (*buf1++)
02119     {
02120       return 0;
02121     }
02122   }
02123 
02124   return 1;
02125 }
02126 
02147 int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
02148 {
02149   int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
02150       frac1=round_up(from1->frac), frac2=round_up(from2->frac),
02151       intg0=round_up(from1->intg+from2->intg),
02152       frac0=frac1+frac2, error, i, j, d_to_move;
02153   dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
02154        *start2, *stop2, *stop1, *start0, carry;
02155 
02156   sanity(to);
02157 
02158   i=intg0;
02159   j=frac0;
02160   fix_intg_frac_error(to->len, intg0, frac0, error);
02161   to->sign=from1->sign != from2->sign;
02162   to->frac=from1->frac+from2->frac;
02163   to->intg=intg0*DIG_PER_DEC1;
02164 
02165   if (unlikely(error))
02166   {
02167     set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
02168     set_if_smaller(to->intg, intg0*DIG_PER_DEC1);
02169     if (unlikely(i > intg0))
02170     {
02171       i-=intg0;
02172       j=i >> 1;
02173       intg1-= j;
02174       intg2-=i-j;
02175       frac1=frac2=0; /* frac0 is already 0 here */
02176     }
02177     else
02178     {
02179       j-=frac0;
02180       i=j >> 1;
02181       frac1-= i;
02182       frac2-=j-i;
02183     }
02184   }
02185   start0=to->buf+intg0+frac0-1;
02186   start2=buf2+frac2-1;
02187   stop1=buf1-intg1;
02188   stop2=buf2-intg2;
02189 
02190   memset(to->buf, 0, (intg0+frac0)*sizeof(dec1));
02191 
02192   for (buf1+=frac1-1; buf1 >= stop1; buf1--, start0--)
02193   {
02194     carry=0;
02195     for (buf0=start0, buf2=start2; buf2 >= stop2; buf2--, buf0--)
02196     {
02197       dec1 hi, lo;
02198       dec2 p= ((dec2)*buf1) * ((dec2)*buf2);
02199       hi=(dec1)(p/DIG_BASE);
02200       lo=(dec1)(p-((dec2)hi)*DIG_BASE);
02201       add2(*buf0, *buf0, lo, carry);
02202       carry+=hi;
02203     }
02204     if (carry)
02205     {
02206       if (buf0 < to->buf)
02207         return E_DEC_OVERFLOW;
02208       add2(*buf0, *buf0, 0, carry);
02209     }
02210     for (buf0--; carry; buf0--)
02211     {
02212       if (buf0 < to->buf)
02213         return E_DEC_OVERFLOW;
02214       add(*buf0, *buf0, 0, carry);
02215     }
02216   }
02217 
02218   /* Now we have to check for -0.000 case */
02219   if (to->sign)
02220   {
02221     dec1 *buf= to->buf;
02222     dec1 *end= to->buf + intg0 + frac0;
02223     assert(buf != end);
02224     for (;;)
02225     {
02226       if (*buf)
02227         break;
02228       if (++buf == end)
02229       {
02230         /* We got decimal zero */
02231         to->set_zero();
02232         break;
02233       }
02234     }
02235   }
02236   buf1= to->buf;
02237   d_to_move= intg0 + round_up(to->frac);
02238   while (!*buf1 && (to->intg > DIG_PER_DEC1))
02239   {
02240     buf1++;
02241     to->intg-= DIG_PER_DEC1;
02242     d_to_move--;
02243   }
02244   if (to->buf < buf1)
02245   {
02246     dec1 *cur_d= to->buf;
02247     for (; d_to_move--; cur_d++, buf1++)
02248       *cur_d= *buf1;
02249   }
02250   return error;
02251 }
02252 
02264 static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
02265                        decimal_t *to, decimal_t *mod, int scale_incr)
02266 {
02267   int frac1=round_up(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
02268       frac2=round_up(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
02269       error= 0, i, intg0, frac0, len1, len2, dintg, div_mod=(!mod);
02270   dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1,
02271        *start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry;
02272   dec2 norm_factor, x, guess, y;
02273 
02274   if (mod)
02275     to=mod;
02276 
02277   sanity(to);
02278 
02279   /* removing all the leading zeroes */
02280   i= ((prec2 - 1) % DIG_PER_DEC1) + 1;
02281   while (prec2 > 0 && *buf2 == 0)
02282   {
02283     prec2-= i;
02284     i= DIG_PER_DEC1;
02285     buf2++;
02286   }
02287   if (prec2 <= 0) /* short-circuit everything: from2 == 0 */
02288     return E_DEC_DIV_ZERO;
02289   for (i= (prec2 - 1) % DIG_PER_DEC1; *buf2 < powers10[i--]; prec2--) ;
02290   assert(prec2 > 0);
02291 
02292   i=((prec1-1) % DIG_PER_DEC1)+1;
02293   while (prec1 > 0 && *buf1 == 0)
02294   {
02295     prec1-=i;
02296     i=DIG_PER_DEC1;
02297     buf1++;
02298   }
02299   if (prec1 <= 0)
02300   { /* short-circuit everything: from1 == 0 */
02301     to->set_zero();
02302     return E_DEC_OK;
02303   }
02304   for (i=(prec1-1) % DIG_PER_DEC1; *buf1 < powers10[i--]; prec1--) ;
02305   assert(prec1 > 0);
02306 
02307   /* let's fix scale_incr, taking into account frac1,frac2 increase */
02308   if ((scale_incr-= frac1 - from1->frac + frac2 - from2->frac) < 0)
02309     scale_incr=0;
02310 
02311   dintg=(prec1-frac1)-(prec2-frac2)+(*buf1 >= *buf2);
02312   if (dintg < 0)
02313   {
02314     dintg/=DIG_PER_DEC1;
02315     intg0=0;
02316   }
02317   else
02318     intg0=round_up(dintg);
02319   if (mod)
02320   {
02321     /* we're calculating N1 % N2.
02322        The result will have
02323          frac=cmax(frac1, frac2), as for subtraction
02324          intg=intg2
02325     */
02326     to->sign=from1->sign;
02327     to->frac=max(from1->frac, from2->frac);
02328     frac0=0;
02329   }
02330   else
02331   {
02332     /*
02333       we're calculating N1/N2. N1 is in the buf1, has prec1 digits
02334       N2 is in the buf2, has prec2 digits. Scales are frac1 and
02335       frac2 accordingly.
02336       Thus, the result will have
02337          frac = round_up(frac1+frac2+scale_incr)
02338       and
02339          intg = (prec1-frac1) - (prec2-frac2) + 1
02340          prec = intg+frac
02341     */
02342     frac0=round_up(frac1+frac2+scale_incr);
02343     fix_intg_frac_error(to->len, intg0, frac0, error);
02344     to->sign=from1->sign != from2->sign;
02345     to->intg=intg0*DIG_PER_DEC1;
02346     to->frac=frac0*DIG_PER_DEC1;
02347   }
02348   buf0=to->buf;
02349   stop0=buf0+intg0+frac0;
02350   if (likely(div_mod))
02351     while (dintg++ < 0)
02352       *buf0++=0;
02353 
02354   len1=(i=round_up(prec1))+round_up(2*frac2+scale_incr+1) + 1;
02355   set_if_bigger(len1, 3);
02356   if (!(tmp1=(dec1 *)alloca(len1*sizeof(dec1))))
02357     return E_DEC_OOM;
02358   memcpy(tmp1, buf1, i*sizeof(dec1));
02359   memset(tmp1+i, 0, (len1-i)*sizeof(dec1));
02360 
02361   start1=tmp1;
02362   stop1=start1+len1;
02363   start2=buf2;
02364   stop2=buf2+round_up(prec2)-1;
02365 
02366   /* removing end zeroes */
02367   while (*stop2 == 0 && stop2 >= start2)
02368     stop2--;
02369   len2= (int) (stop2++ - start2);
02370 
02371   /*
02372     calculating norm2 (normalized *start2) - we need *start2 to be large
02373     (at least > DIG_BASE/2), but unlike Knuth's Alg. D we don't want to
02374     normalize input numbers (as we don't make a copy of the divisor).
02375     Thus we normalize first dec1 of buf2 only, and we'll normalize *start1
02376     on the fly for the purpose of guesstimation only.
02377     It's also faster, as we're saving on normalization of buf2
02378   */
02379   norm_factor=DIG_BASE/(*start2+1);
02380   norm2=(dec1)(norm_factor*start2[0]);
02381   if (likely(len2>0))
02382     norm2+=(dec1)(norm_factor*start2[1]/DIG_BASE);
02383 
02384   if (*start1 < *start2)
02385     dcarry=*start1++;
02386   else
02387     dcarry=0;
02388 
02389   /* main loop */
02390   for (; buf0 < stop0; buf0++)
02391   {
02392     /* short-circuit, if possible */
02393     if (unlikely(dcarry == 0 && *start1 < *start2))
02394       guess=0;
02395     else
02396     {
02397       /* D3: make a guess */
02398       x=start1[0]+((dec2)dcarry)*DIG_BASE;
02399       y=start1[1];
02400       guess=(norm_factor*x+norm_factor*y/DIG_BASE)/norm2;
02401       if (unlikely(guess >= DIG_BASE))
02402         guess=DIG_BASE-1;
02403       if (likely(len2>0))
02404       {
02405         /* hmm, this is a suspicious trick - I removed normalization here */
02406         if (start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y)
02407           guess--;
02408         if (unlikely(start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y))
02409           guess--;
02410         assert(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y);
02411       }
02412 
02413       /* D4: multiply and subtract */
02414       buf2=stop2;
02415       buf1=start1+len2;
02416       assert(buf1 < stop1);
02417       for (carry=0; buf2 > start2; buf1--)
02418       {
02419         dec1 hi, lo;
02420         x=guess * (*--buf2);
02421         hi=(dec1)(x/DIG_BASE);
02422         lo=(dec1)(x-((dec2)hi)*DIG_BASE);
02423         sub2(*buf1, *buf1, lo, carry);
02424         carry+=hi;
02425       }
02426       carry= dcarry < carry;
02427 
02428       /* D5: check the remainder */
02429       if (unlikely(carry))
02430       {
02431         /* D6: correct the guess */
02432         guess--;
02433         buf2=stop2;
02434         buf1=start1+len2;
02435         for (carry=0; buf2 > start2; buf1--)
02436         {
02437           add(*buf1, *buf1, *--buf2, carry);
02438         }
02439       }
02440     }
02441     if (likely(div_mod))
02442       *buf0=(dec1)guess;
02443     dcarry= *start1;
02444     start1++;
02445   }
02446   if (mod)
02447   {
02448     /*
02449       now the result is in tmp1, it has
02450         intg=prec1-frac1
02451         frac=cmax(frac1, frac2)=to->frac
02452     */
02453     if (dcarry)
02454       *--start1=dcarry;
02455     buf0=to->buf;
02456     intg0=(int) (round_up(prec1-frac1)-(start1-tmp1));
02457     frac0=round_up(to->frac);
02458     error=E_DEC_OK;
02459     if (unlikely(frac0==0 && intg0==0))
02460     {
02461       to->set_zero();
02462       goto done;
02463     }
02464     if (intg0<=0)
02465     {
02466       if (unlikely(-intg0 >= to->len))
02467       {
02468         to->set_zero();
02469         error=E_DEC_TRUNCATED;
02470         goto done;
02471       }
02472       stop1=start1+frac0;
02473       frac0+=intg0;
02474       to->intg=0;
02475       while (intg0++ < 0)
02476         *buf0++=0;
02477     }
02478     else
02479     {
02480       if (unlikely(intg0 > to->len))
02481       {
02482         frac0=0;
02483         intg0=to->len;
02484         error=E_DEC_OVERFLOW;
02485         goto done;
02486       }
02487       assert(intg0 <= round_up(from2->intg));
02488       stop1=start1+frac0+intg0;
02489       to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
02490     }
02491     if (unlikely(intg0+frac0 > to->len))
02492     {
02493       stop1-=frac0+intg0-to->len;
02494       frac0=to->len-intg0;
02495       to->frac=frac0*DIG_PER_DEC1;
02496         error=E_DEC_TRUNCATED;
02497     }
02498     assert(buf0 + (stop1 - start1) <= to->buf + to->len);
02499     while (start1 < stop1)
02500         *buf0++=*start1++;
02501   }
02502 done:
02503   return error;
02504 }
02505 
02519 int
02520 decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, int scale_incr)
02521 {
02522   return do_div_mod(from1, from2, to, 0, scale_incr);
02523 }
02524 
02550 int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
02551 {
02552   return do_div_mod(from1, from2, 0, to, 0);
02553 }
02554 
02555 std::ostream& operator<<(std::ostream& output, const type::Decimal &dec)
02556 {
02557   drizzled::String str;
02558 
02559   class_decimal2string(&dec, 0, &str);
02560 
02561   output << "type::Decimal:(";
02562   output <<  str.c_ptr();
02563   output << ")";
02564 
02565   return output;  // for multiple << operators.
02566 }
02567 
02568 } /* namespace drizzled */
02569 
02570 #ifdef MAIN
02571 
02572 int full= 0;
02573 decimal_t a, b, c;
02574 char buf1[100], buf2[100], buf3[100];
02575 
02576 void dump_decimal(decimal_t *d)
02577 {
02578   int i;
02579   printf("/* intg=%d, frac=%d, sign=%d, buf[]={", d->intg, d->frac, d->sign);
02580   for (i=0; i < round_up(d->frac)+round_up(d->intg)-1; i++)
02581     printf("%09d, ", d->buf[i]);
02582   printf("%09d} */ ", d->buf[i]);
02583 }
02584 
02585 
02586 void check_result_code(int actual, int want)
02587 {
02588   if (actual != want)
02589   {
02590     printf("\n^^^^^^^^^^^^^ must return %d\n", want);
02591     exit(1);
02592   }
02593 }
02594 
02595 
02596 void print_decimal(decimal_t *d, const char *orig, int actual, int want)
02597 {
02598   char s[100];
02599   int slen=sizeof(s);
02600 
02601   if (full) dump_decimal(d);
02602   decimal2string(d, s, &slen, 0, 0, 0);
02603   printf("'%s'", s);
02604   check_result_code(actual, want);
02605   if (orig && strcmp(orig, s))
02606   {
02607     printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
02608     exit(1);
02609   }
02610 }
02611 
02612 void test_d2s()
02613 {
02614   char s[100];
02615   int slen, res;
02616 
02617   /***********************************/
02618   printf("==== decimal2string ====\n");
02619   a.buf[0]=12345; a.intg=5; a.frac=0; a.sign=0;
02620   slen=sizeof(s);
02621   res=decimal2string(&a, s, &slen, 0, 0, 0);
02622   dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
02623 
02624   a.buf[1]=987000000; a.frac=3;
02625   slen=sizeof(s);
02626   res=decimal2string(&a, s, &slen, 0, 0, 0);
02627   dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
02628 
02629   a.sign=1;
02630   slen=sizeof(s);
02631   res=decimal2string(&a, s, &slen, 0, 0, 0);
02632   dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
02633 
02634   slen=8;
02635   res=decimal2string(&a, s, &slen, 0, 0, 0);
02636   dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
02637 
02638   slen=5;
02639   res=decimal2string(&a, s, &slen, 0, 0, 0);
02640   dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
02641 
02642   a.buf[0]=987000000; a.frac=3; a.intg=0;
02643   slen=sizeof(s);
02644   res=decimal2string(&a, s, &slen, 0, 0, 0);
02645   dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
02646 }
02647 
02648 void test_s2d(const char *s, const char *orig, int ex)
02649 {
02650   char s1[100], *end;
02651   int res;
02652   snprintf(s1, sizeof(s1), "'%s'", s);
02653   end= strend(s);
02654   printf("len=%2d %-30s => res=%d    ", a.len, s1,
02655          (res= string2decimal(s, &a, &end)));
02656   print_decimal(&a, orig, res, ex);
02657   printf("\n");
02658 }
02659 
02660 void test_d2f(const char *s, int ex)
02661 {
02662   char s1[100], *end;
02663   double x;
02664   int res;
02665 
02666   snprintf(s1, sizeof(s1), "'%s'", s);
02667   end= strend(s);
02668   string2decimal(s, &a, &end);
02669   res=decimal2double(&a, &x);
02670   if (full) dump_decimal(&a);
02671   printf("%-40s => res=%d    %.*g\n", s1, res, a.intg+a.frac, x);
02672   check_result_code(res, ex);
02673 }
02674 
02675 void test_d2b2d(const char *str, int p, int s, const char *orig, int ex)
02676 {
02677   char s1[100], buf[100], *end;
02678   int res, i, size=decimal_bin_size(p, s);
02679 
02680   snprintf(s1, sizeof(s1), "'%s'", str);
02681   end= strend(str);
02682   string2decimal(str, &a, &end);
02683   res=decimal2bin(&a, buf, p, s);
02684   printf("%-31s {%2d, %2d} => res=%d size=%-2d ", s1, p, s, res, size);
02685   if (full)
02686   {
02687     printf("0x");
02688     for (i=0; i < size; i++)
02689       printf("%02x", ((unsigned char *)buf)[i]);
02690   }
02691   res=bin2decimal(buf, &a, p, s);
02692   printf(" => res=%d ", res);
02693   print_decimal(&a, orig, res, ex);
02694   printf("\n");
02695 }
02696 
02697 void test_f2d(double from, int ex)
02698 {
02699   int res;
02700 
02701   res=double2decimal(from, &a);
02702   printf("%-40.*f => res=%d    ", DBL_DIG-2, from, res);
02703   print_decimal(&a, 0, res, ex);
02704   printf("\n");
02705 }
02706 
02707 void test_ull2d(uint64_t from, const char *orig, int ex)
02708 {
02709   char s[100];
02710   int res;
02711 
02712   res=uint64_t2decimal(from, &a);
02713   internal::int64_t10_to_str(from,s,10);
02714   printf("%-40s => res=%d    ", s, res);
02715   print_decimal(&a, orig, res, ex);
02716   printf("\n");
02717 }
02718 
02719 void test_ll2d(int64_t from, const char *orig, int ex)
02720 {
02721   char s[100];
02722   int res;
02723 
02724   res=int64_t2decimal(from, &a);
02725   internal::int64_t10_to_str(from,s,-10);
02726   printf("%-40s => res=%d    ", s, res);
02727   print_decimal(&a, orig, res, ex);
02728   printf("\n");
02729 }
02730 
02731 void test_d2ull(const char *s, const char *orig, int ex)
02732 {
02733   char s1[100], *end;
02734   uint64_t x;
02735   int res;
02736 
02737   end= strend(s);
02738   string2decimal(s, &a, &end);
02739   res=decimal2uint64_t(&a, &x);
02740   if (full) dump_decimal(&a);
02741   internal::int64_t10_to_str(x,s1,10);
02742   printf("%-40s => res=%d    %s\n", s, res, s1);
02743   check_result_code(res, ex);
02744   if (orig && strcmp(orig, s1))
02745   {
02746     printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
02747     exit(1);
02748   }
02749 }
02750 
02751 void test_d2ll(const char *s, const char *orig, int ex)
02752 {
02753   char s1[100], *end;
02754   int64_t x;
02755   int res;
02756 
02757   end= strend(s);
02758   string2decimal(s, &a, &end);
02759   res=decimal2int64_t(&a, &x);
02760   if (full) dump_decimal(&a);
02761   internal::int64_t10_to_str(x,s1,-10);
02762   printf("%-40s => res=%d    %s\n", s, res, s1);
02763   check_result_code(res, ex);
02764   if (orig && strcmp(orig, s1))
02765   {
02766     printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
02767     exit(1);
02768   }
02769 }
02770 
02771 void test_da(const char *s1, const char *s2, const char *orig, int ex)
02772 {
02773   char s[100], *end;
02774   int res;
02775   snprintf(s, sizeof(s), "'%s' + '%s'", s1, s2);
02776   end= strend(s1);
02777   string2decimal(s1, &a, &end);
02778   end= strend(s2);
02779   string2decimal(s2, &b, &end);
02780   res=decimal_add(&a, &b, &c);
02781   printf("%-40s => res=%d    ", s, res);
02782   print_decimal(&c, orig, res, ex);
02783   printf("\n");
02784 }
02785 
02786 void test_ds(const char *s1, const char *s2, const char *orig, int ex)
02787 {
02788   char s[100], *end;
02789   int res;
02790   snprintf(s, sizeof(s), "'%s' - '%s'", s1, s2);
02791   end= strend(s1);
02792   string2decimal(s1, &a, &end);
02793   end= strend(s2);
02794   string2decimal(s2, &b, &end);
02795   res=decimal_sub(&a, &b, &c);
02796   printf("%-40s => res=%d    ", s, res);
02797   print_decimal(&c, orig, res, ex);
02798   printf("\n");
02799 }
02800 
02801 void test_dc(const char *s1, const char *s2, int orig)
02802 {
02803   char s[100], *end;
02804   int res;
02805   snprintf(s, sizeof(s), "'%s' <=> '%s'", s1, s2);
02806   end= strend(s1);
02807   string2decimal(s1, &a, &end);
02808   end= strend(s2);
02809   string2decimal(s2, &b, &end);
02810   res=decimal_cmp(&a, &b);
02811   printf("%-40s => res=%d\n", s, res);
02812   if (orig != res)
02813   {
02814     printf("\n^^^^^^^^^^^^^ must've been %d\n", orig);
02815     exit(1);
02816   }
02817 }
02818 
02819 void test_dm(const char *s1, const char *s2, const char *orig, int ex)
02820 {
02821   char s[100], *end;
02822   int res;
02823   snprintf(s, sizeof(s), "'%s' * '%s'", s1, s2);
02824   end= strend(s1);
02825   string2decimal(s1, &a, &end);
02826   end= strend(s2);
02827   string2decimal(s2, &b, &end);
02828   res=decimal_mul(&a, &b, &c);
02829   printf("%-40s => res=%d    ", s, res);
02830   print_decimal(&c, orig, res, ex);
02831   printf("\n");
02832 }
02833 
02834 void test_dv(const char *s1, const char *s2, const char *orig, int ex)
02835 {
02836   char s[100], *end;
02837   int res;
02838   snprintf(s, sizeof(s), "'%s' / '%s'", s1, s2);
02839   end= strend(s1);
02840   string2decimal(s1, &a, &end);
02841   end= strend(s2);
02842   string2decimal(s2, &b, &end);
02843   res=decimal_div(&a, &b, &c, 5);
02844   printf("%-40s => res=%d    ", s, res);
02845   check_result_code(res, ex);
02846   if (res == E_DEC_DIV_ZERO)
02847     printf("E_DEC_DIV_ZERO");
02848   else
02849     print_decimal(&c, orig, res, ex);
02850   printf("\n");
02851 }
02852 
02853 void test_md(const char *s1, const char *s2, const char *orig, int ex)
02854 {
02855   char s[100], *end;
02856   int res;
02857   snprintf(s, sizeof(s), "'%s' %% '%s'", s1, s2);
02858   end= strend(s1);
02859   string2decimal(s1, &a, &end);
02860   end= strend(s2);
02861   string2decimal(s2, &b, &end);
02862   res=decimal_mod(&a, &b, &c);
02863   printf("%-40s => res=%d    ", s, res);
02864   check_result_code(res, ex);
02865   if (res == E_DEC_DIV_ZERO)
02866     printf("E_DEC_DIV_ZERO");
02867   else
02868     print_decimal(&c, orig, res, ex);
02869   printf("\n");
02870 }
02871 
02872 const char *round_mode[]=
02873 {"TRUNCATE", "HALF_EVEN", "HALF_UP", "CEILING", "FLOOR"};
02874 
02875 void test_ro(const char *s1, int n, decimal_round_mode mode, const char *orig,
02876              int ex)
02877 {
02878   char s[100], *end;
02879   int res;
02880   snprintf(s, sizeof(s), "'%s', %d, %s", s1, n, round_mode[mode]);
02881   end= strend(s1);
02882   string2decimal(s1, &a, &end);
02883   res=decimal_round(&a, &b, n, mode);
02884   printf("%-40s => res=%d    ", s, res);
02885   print_decimal(&b, orig, res, ex);
02886   printf("\n");
02887 }
02888 
02889 
02890 void test_mx(int precision, int frac, const char *orig)
02891 {
02892   char s[100];
02893   snprintf(s, sizeof(s), "%d, %d", precision, frac);
02894   max_decimal(precision, frac, &a);
02895   printf("%-40s =>          ", s);
02896   print_decimal(&a, orig, 0, 0);
02897   printf("\n");
02898 }
02899 
02900 
02901 void test_pr(const char *s1, int prec, int dec, char filler, const char *orig,
02902              int ex)
02903 {
02904   char s[100], *end;
02905   char s2[100];
02906   int slen= sizeof(s2);
02907   int res;
02908 
02909   snprintf(s, sizeof(s), filler ? "'%s', %d, %d, '%c'" : "'%s', %d, %d, '\\0'",
02910           s1, prec, dec, filler);
02911   end= strend(s1);
02912   string2decimal(s1, &a, &end);
02913   res= decimal2string(&a, s2, &slen, prec, dec, filler);
02914   printf("%-40s => res=%d    '%s'", s, res, s2);
02915   check_result_code(res, ex);
02916   if (orig && strcmp(orig, s2))
02917   {
02918     printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
02919     exit(1);
02920   }
02921   printf("\n");
02922 }
02923 
02924 
02925 void test_sh(const char *s1, int shift, const char *orig, int ex)
02926 {
02927   char s[100], *end;
02928   int res;
02929   snprintf(s, sizeof(s), "'%s' %s %d", s1, ((shift < 0) ? ">>" : "<<"), abs(shift));
02930   end= strend(s1);
02931   string2decimal(s1, &a, &end);
02932   res= decimal_shift(&a, shift);
02933   printf("%-40s => res=%d    ", s, res);
02934   print_decimal(&a, orig, res, ex);
02935   printf("\n");
02936 }
02937 
02938 
02939 void test_fr(const char *s1, const char *orig)
02940 {
02941   char s[100], *end;
02942   snprintf(s, sizeof(s), "'%s'", s1);
02943   printf("%-40s =>          ", s);
02944   end= strend(s1);
02945   string2decimal(s1, &a, &end);
02946   a.frac= decimal_actual_fraction(&a);
02947   print_decimal(&a, orig, 0, 0);
02948   printf("\n");
02949 }
02950 
02951 
02952 int main()
02953 {
02954   a.buf=(void*)buf1;
02955   a.len=sizeof(buf1)/sizeof(dec1);
02956   b.buf=(void*)buf2;
02957   b.len=sizeof(buf2)/sizeof(dec1);
02958   c.buf=(void*)buf3;
02959   c.len=sizeof(buf3)/sizeof(dec1);
02960 
02961   if (full)
02962     test_d2s();
02963 
02964   printf("==== string2decimal ====\n");
02965   test_s2d("12345", "12345", 0);
02966   test_s2d("12345.", "12345", 0);
02967   test_s2d("123.45", "123.45", 0);
02968   test_s2d("-123.45", "-123.45", 0);
02969   test_s2d(".00012345000098765", "0.00012345000098765", 0);
02970   test_s2d(".12345000098765", "0.12345000098765", 0);
02971   test_s2d("-.000000012345000098765", "-0.000000012345000098765", 0);
02972   test_s2d("1234500009876.5", "1234500009876.5", 0);
02973   a.len=1;
02974   test_s2d("123450000098765", "98765", 2);
02975   test_s2d("123450.000098765", "123450", 1);
02976   a.len=sizeof(buf1)/sizeof(dec1);
02977   test_s2d("123E5", "12300000", 0);
02978   test_s2d("123E-2", "1.23", 0);
02979 
02980   printf("==== decimal2double ====\n");
02981   test_d2f("12345", 0);
02982   test_d2f("123.45", 0);
02983   test_d2f("-123.45", 0);
02984   test_d2f("0.00012345000098765", 0);
02985   test_d2f("1234500009876.5", 0);
02986 
02987   printf("==== double2decimal ====\n");
02988   test_f2d(12345, 0);
02989   test_f2d(1.0/3, 0);
02990   test_f2d(-123.45, 0);
02991   test_f2d(0.00012345000098765, 0);
02992   test_f2d(1234500009876.5, 0);
02993 
02994   printf("==== uint64_t2decimal ====\n");
02995   test_ull2d(12345ULL, "12345", 0);
02996   test_ull2d(0ULL, "0", 0);
02997   test_ull2d(18446744073709551615ULL, "18446744073709551615", 0);
02998 
02999   printf("==== decimal2uint64_t ====\n");
03000   test_d2ull("12345", "12345", 0);
03001   test_d2ull("0", "0", 0);
03002   test_d2ull("18446744073709551615", "18446744073709551615", 0);
03003   test_d2ull("18446744073709551616", "18446744073", 2);
03004   test_d2ull("-1", "0", 2);
03005   test_d2ull("1.23", "1", 1);
03006   test_d2ull("9999999999999999999999999.000", "9999999999999999", 2);
03007 
03008   printf("==== int64_t2decimal ====\n");
03009   test_ll2d(12345LL, "-12345", 0);
03010   test_ll2d(1LL, "-1", 0);
03011   test_ll2d(9223372036854775807LL, "-9223372036854775807", 0);
03012   test_ll2d(9223372036854775808ULL, "-9223372036854775808", 0);
03013 
03014   printf("==== decimal2int64_t ====\n");
03015   test_d2ll("18446744073709551615", "18446744073", 2);
03016   test_d2ll("-1", "-1", 0);
03017   test_d2ll("-1.23", "-1", 1);
03018   test_d2ll("-9223372036854775807", "-9223372036854775807", 0);
03019   test_d2ll("-9223372036854775808", "-9223372036854775808", 0);
03020   test_d2ll("9223372036854775808", "9223372036854775807", 2);
03021 
03022   printf("==== do_add ====\n");
03023   test_da(".00012345000098765" ,"123.45", "123.45012345000098765", 0);
03024   test_da(".1" ,".45", "0.55", 0);
03025   test_da("1234500009876.5" ,".00012345000098765", "1234500009876.50012345000098765", 0);
03026   test_da("9999909999999.5" ,".555", "9999910000000.055", 0);
03027   test_da("99999999" ,"1", "100000000", 0);
03028   test_da("989999999" ,"1", "990000000", 0);
03029   test_da("999999999" ,"1", "1000000000", 0);
03030   test_da("12345" ,"123.45", "12468.45", 0);
03031   test_da("-12345" ,"-123.45", "-12468.45", 0);
03032   test_ds("-12345" ,"123.45", "-12468.45", 0);
03033   test_ds("12345" ,"-123.45", "12468.45", 0);
03034 
03035   printf("==== do_sub ====\n");
03036   test_ds(".00012345000098765", "123.45","-123.44987654999901235", 0);
03037   test_ds("1234500009876.5", ".00012345000098765","1234500009876.49987654999901235", 0);
03038   test_ds("9999900000000.5", ".555","9999899999999.945", 0);
03039   test_ds("1111.5551", "1111.555","0.0001", 0);
03040   test_ds(".555", ".555","0", 0);
03041   test_ds("10000000", "1","9999999", 0);
03042   test_ds("1000001000", ".1","1000000999.9", 0);
03043   test_ds("1000000000", ".1","999999999.9", 0);
03044   test_ds("12345", "123.45","12221.55", 0);
03045   test_ds("-12345", "-123.45","-12221.55", 0);
03046   test_da("-12345", "123.45","-12221.55", 0);
03047   test_da("12345", "-123.45","12221.55", 0);
03048   test_ds("123.45", "12345","-12221.55", 0);
03049   test_ds("-123.45", "-12345","12221.55", 0);
03050   test_da("123.45", "-12345","-12221.55", 0);
03051   test_da("-123.45", "12345","12221.55", 0);
03052   test_da("5", "-6.0","-1.0", 0);
03053 
03054   printf("==== decimal_mul ====\n");
03055   test_dm("12", "10","120", 0);
03056   test_dm("-123.456", "98765.4321","-12193185.1853376", 0);
03057   test_dm("-123456000000", "98765432100000","-12193185185337600000000000", 0);
03058   test_dm("123456", "987654321","121931851853376", 0);
03059   test_dm("123456", "9876543210","1219318518533760", 0);
03060   test_dm("123", "0.01","1.23", 0);
03061   test_dm("123", "0","0", 0);
03062 
03063   printf("==== decimal_div ====\n");
03064   test_dv("120", "10","12.000000000", 0);
03065   test_dv("123", "0.01","12300.000000000", 0);
03066   test_dv("120", "100000000000.00000","0.000000001200000000", 0);
03067   test_dv("123", "0","", 4);
03068   test_dv("0", "0", "", 4);
03069   test_dv("-12193185.1853376", "98765.4321","-123.456000000000000000", 0);
03070   test_dv("121931851853376", "987654321","123456.000000000", 0);
03071   test_dv("0", "987","0", 0);
03072   test_dv("1", "3","0.333333333", 0);
03073   test_dv("1.000000000000", "3","0.333333333333333333", 0);
03074   test_dv("1", "1","1.000000000", 0);
03075   test_dv("0.0123456789012345678912345", "9999999999","0.000000000001234567890246913578148141", 0);
03076   test_dv("10.333000000", "12.34500","0.837019036046982584042122316", 0);
03077   test_dv("10.000000000060", "2","5.000000000030000000", 0);
03078 
03079   printf("==== decimal_mod ====\n");
03080   test_md("234","10","4", 0);
03081   test_md("234.567","10.555","2.357", 0);
03082   test_md("-234.567","10.555","-2.357", 0);
03083   test_md("234.567","-10.555","2.357", 0);
03084   c.buf[1]=0x3ABECA;
03085   test_md("99999999999999999999999999999999999999","3","0", 0);
03086   if (c.buf[1] != 0x3ABECA)
03087   {
03088     printf("%X - overflow\n", c.buf[1]);
03089     exit(1);
03090   }
03091 
03092   printf("==== decimal2bin/bin2decimal ====\n");
03093   test_d2b2d("-10.55", 4, 2,"-10.55", 0);
03094   test_d2b2d("0.0123456789012345678912345", 30, 25,"0.0123456789012345678912345", 0);
03095   test_d2b2d("12345", 5, 0,"12345", 0);
03096   test_d2b2d("12345", 10, 3,"12345.000", 0);
03097   test_d2b2d("123.45", 10, 3,"123.450", 0);
03098   test_d2b2d("-123.45", 20, 10,"-123.4500000000", 0);
03099   test_d2b2d(".00012345000098765", 15, 14,"0.00012345000098", 0);
03100   test_d2b2d(".00012345000098765", 22, 20,"0.00012345000098765000", 0);
03101   test_d2b2d(".12345000098765", 30, 20,"0.12345000098765000000", 0);
03102   test_d2b2d("-.000000012345000098765", 30, 20,"-0.00000001234500009876", 0);
03103   test_d2b2d("1234500009876.5", 30, 5,"1234500009876.50000", 0);
03104   test_d2b2d("111111111.11", 10, 2,"11111111.11", 0);
03105   test_d2b2d("000000000.01", 7, 3,"0.010", 0);
03106   test_d2b2d("123.4", 10, 2, "123.40", 0);
03107 
03108 
03109   printf("==== decimal_cmp ====\n");
03110   test_dc("12","13",-1);
03111   test_dc("13","12",1);
03112   test_dc("-10","10",-1);
03113   test_dc("10","-10",1);
03114   test_dc("-12","-13",1);
03115   test_dc("0","12",-1);
03116   test_dc("-10","0",-1);
03117   test_dc("4","4",0);
03118 
03119   printf("==== decimal_round ====\n");
03120   test_ro("5678.123451",-4,TRUNCATE,"0", 0);
03121   test_ro("5678.123451",-3,TRUNCATE,"5000", 0);
03122   test_ro("5678.123451",-2,TRUNCATE,"5600", 0);
03123   test_ro("5678.123451",-1,TRUNCATE,"5670", 0);
03124   test_ro("5678.123451",0,TRUNCATE,"5678", 0);
03125   test_ro("5678.123451",1,TRUNCATE,"5678.1", 0);
03126   test_ro("5678.123451",2,TRUNCATE,"5678.12", 0);
03127   test_ro("5678.123451",3,TRUNCATE,"5678.123", 0);
03128   test_ro("5678.123451",4,TRUNCATE,"5678.1234", 0);
03129   test_ro("5678.123451",5,TRUNCATE,"5678.12345", 0);
03130   test_ro("5678.123451",6,TRUNCATE,"5678.123451", 0);
03131   test_ro("-5678.123451",-4,TRUNCATE,"0", 0);
03132   memset(buf2, 33, sizeof(buf2));
03133   test_ro("99999999999999999999999999999999999999",-31,TRUNCATE,"99999990000000000000000000000000000000", 0);
03134   test_ro("15.1",0,HALF_UP,"15", 0);
03135   test_ro("15.5",0,HALF_UP,"16", 0);
03136   test_ro("15.9",0,HALF_UP,"16", 0);
03137   test_ro("-15.1",0,HALF_UP,"-15", 0);
03138   test_ro("-15.5",0,HALF_UP,"-16", 0);
03139   test_ro("-15.9",0,HALF_UP,"-16", 0);
03140   test_ro("15.1",1,HALF_UP,"15.1", 0);
03141   test_ro("-15.1",1,HALF_UP,"-15.1", 0);
03142   test_ro("15.17",1,HALF_UP,"15.2", 0);
03143   test_ro("15.4",-1,HALF_UP,"20", 0);
03144   test_ro("-15.4",-1,HALF_UP,"-20", 0);
03145   test_ro("5.4",-1,HALF_UP,"10", 0);
03146   test_ro(".999", 0, HALF_UP, "1", 0);
03147   memset(buf2, 33, sizeof(buf2));
03148   test_ro("999999999", -9, HALF_UP, "1000000000", 0);
03149   test_ro("15.1",0,HALF_EVEN,"15", 0);
03150   test_ro("15.5",0,HALF_EVEN,"16", 0);
03151   test_ro("14.5",0,HALF_EVEN,"14", 0);
03152   test_ro("15.9",0,HALF_EVEN,"16", 0);
03153   test_ro("15.1",0,CEILING,"16", 0);
03154   test_ro("-15.1",0,CEILING,"-15", 0);
03155   test_ro("15.1",0,FLOOR,"15", 0);
03156   test_ro("-15.1",0,FLOOR,"-16", 0);
03157   test_ro("999999999999999999999.999", 0, CEILING,"1000000000000000000000", 0);
03158   test_ro("-999999999999999999999.999", 0, FLOOR,"-1000000000000000000000", 0);
03159 
03160   b.buf[0]=DIG_BASE+1;
03161   b.buf++;
03162   test_ro(".3", 0, HALF_UP, "0", 0);
03163   b.buf--;
03164   if (b.buf[0] != DIG_BASE+1)
03165   {
03166     printf("%d - underflow\n", b.buf[0]);
03167     exit(1);
03168   }
03169 
03170   printf("==== max_decimal ====\n");
03171   test_mx(1,1,"0.9");
03172   test_mx(1,0,"9");
03173   test_mx(2,1,"9.9");
03174   test_mx(4,2,"99.99");
03175   test_mx(6,3,"999.999");
03176   test_mx(8,4,"9999.9999");
03177   test_mx(10,5,"99999.99999");
03178   test_mx(12,6,"999999.999999");
03179   test_mx(14,7,"9999999.9999999");
03180   test_mx(16,8,"99999999.99999999");
03181   test_mx(18,9,"999999999.999999999");
03182   test_mx(20,10,"9999999999.9999999999");
03183   test_mx(20,20,"0.99999999999999999999");
03184   test_mx(20,0,"99999999999999999999");
03185   test_mx(40,20,"99999999999999999999.99999999999999999999");
03186 
03187   printf("==== decimal2string ====\n");
03188   test_pr("123.123", 0, 0, 0, "123.123", 0);
03189   test_pr("123.123", 7, 3, '0', "123.123", 0);
03190   test_pr("123.123", 9, 3, '0', "00123.123", 0);
03191   test_pr("123.123", 9, 4, '0', "0123.1230", 0);
03192   test_pr("123.123", 9, 5, '0', "123.12300", 0);
03193   test_pr("123.123", 9, 2, '0', "000123.12", 1);
03194   test_pr("123.123", 9, 6, '0', "23.123000", 2);
03195 
03196   printf("==== decimal_shift ====\n");
03197   test_sh("123.123", 1, "1231.23", 0);
03198   test_sh("123457189.123123456789000", 1, "1234571891.23123456789", 0);
03199   test_sh("123457189.123123456789000", 4, "1234571891231.23456789", 0);
03200   test_sh("123457189.123123456789000", 8, "12345718912312345.6789", 0);
03201   test_sh("123457189.123123456789000", 9, "123457189123123456.789", 0);
03202   test_sh("123457189.123123456789000", 10, "1234571891231234567.89", 0);
03203   test_sh("123457189.123123456789000", 17, "12345718912312345678900000", 0);
03204   test_sh("123457189.123123456789000", 18, "123457189123123456789000000", 0);
03205   test_sh("123457189.123123456789000", 19, "1234571891231234567890000000", 0);
03206   test_sh("123457189.123123456789000", 26, "12345718912312345678900000000000000", 0);
03207   test_sh("123457189.123123456789000", 27, "123457189123123456789000000000000000", 0);
03208   test_sh("123457189.123123456789000", 28, "1234571891231234567890000000000000000", 0);
03209   test_sh("000000000000000000000000123457189.123123456789000", 26, "12345718912312345678900000000000000", 0);
03210   test_sh("00000000123457189.123123456789000", 27, "123457189123123456789000000000000000", 0);
03211   test_sh("00000000000000000123457189.123123456789000", 28, "1234571891231234567890000000000000000", 0);
03212   test_sh("123", 1, "1230", 0);
03213   test_sh("123", 10, "1230000000000", 0);
03214   test_sh(".123", 1, "1.23", 0);
03215   test_sh(".123", 10, "1230000000", 0);
03216   test_sh(".123", 14, "12300000000000", 0);
03217   test_sh("000.000", 1000, "0", 0);
03218   test_sh("000.", 1000, "0", 0);
03219   test_sh(".000", 1000, "0", 0);
03220   test_sh("1", 1000, "1", 2);
03221   test_sh("123.123", -1, "12.3123", 0);
03222   test_sh("123987654321.123456789000", -1, "12398765432.1123456789", 0);
03223   test_sh("123987654321.123456789000", -2, "1239876543.21123456789", 0);
03224   test_sh("123987654321.123456789000", -3, "123987654.321123456789", 0);
03225   test_sh("123987654321.123456789000", -8, "1239.87654321123456789", 0);
03226   test_sh("123987654321.123456789000", -9, "123.987654321123456789", 0);
03227   test_sh("123987654321.123456789000", -10, "12.3987654321123456789", 0);
03228   test_sh("123987654321.123456789000", -11, "1.23987654321123456789", 0);
03229   test_sh("123987654321.123456789000", -12, "0.123987654321123456789", 0);
03230   test_sh("123987654321.123456789000", -13, "0.0123987654321123456789", 0);
03231   test_sh("123987654321.123456789000", -14, "0.00123987654321123456789", 0);
03232   test_sh("00000087654321.123456789000", -14, "0.00000087654321123456789", 0);
03233   a.len= 2;
03234   test_sh("123.123", -2, "1.23123", 0);
03235   test_sh("123.123", -3, "0.123123", 0);
03236   test_sh("123.123", -6, "0.000123123", 0);
03237   test_sh("123.123", -7, "0.0000123123", 0);
03238   test_sh("123.123", -15, "0.000000000000123123", 0);
03239   test_sh("123.123", -16, "0.000000000000012312", 1);
03240   test_sh("123.123", -17, "0.000000000000001231", 1);
03241   test_sh("123.123", -18, "0.000000000000000123", 1);
03242   test_sh("123.123", -19, "0.000000000000000012", 1);
03243   test_sh("123.123", -20, "0.000000000000000001", 1);
03244   test_sh("123.123", -21, "0", 1);
03245   test_sh(".000000000123", -1, "0.0000000000123", 0);
03246   test_sh(".000000000123", -6, "0.000000000000000123", 0);
03247   test_sh(".000000000123", -7, "0.000000000000000012", 1);
03248   test_sh(".000000000123", -8, "0.000000000000000001", 1);
03249   test_sh(".000000000123", -9, "0", 1);
03250   test_sh(".000000000123", 1, "0.00000000123", 0);
03251   test_sh(".000000000123", 8, "0.0123", 0);
03252   test_sh(".000000000123", 9, "0.123", 0);
03253   test_sh(".000000000123", 10, "1.23", 0);
03254   test_sh(".000000000123", 17, "12300000", 0);
03255   test_sh(".000000000123", 18, "123000000", 0);
03256   test_sh(".000000000123", 19, "1230000000", 0);
03257   test_sh(".000000000123", 20, "12300000000", 0);
03258   test_sh(".000000000123", 21, "123000000000", 0);
03259   test_sh(".000000000123", 22, "1230000000000", 0);
03260   test_sh(".000000000123", 23, "12300000000000", 0);
03261   test_sh(".000000000123", 24, "123000000000000", 0);
03262   test_sh(".000000000123", 25, "1230000000000000", 0);
03263   test_sh(".000000000123", 26, "12300000000000000", 0);
03264   test_sh(".000000000123", 27, "123000000000000000", 0);
03265   test_sh(".000000000123", 28, "0.000000000123", 2);
03266   test_sh("123456789.987654321", -1, "12345678.998765432", 1);
03267   test_sh("123456789.987654321", -2, "1234567.899876543", 1);
03268   test_sh("123456789.987654321", -8, "1.234567900", 1);
03269   test_sh("123456789.987654321", -9, "0.123456789987654321", 0);
03270   test_sh("123456789.987654321", -10, "0.012345678998765432", 1);
03271   test_sh("123456789.987654321", -17, "0.000000001234567900", 1);
03272   test_sh("123456789.987654321", -18, "0.000000000123456790", 1);
03273   test_sh("123456789.987654321", -19, "0.000000000012345679", 1);
03274   test_sh("123456789.987654321", -26, "0.000000000000000001", 1);
03275   test_sh("123456789.987654321", -27, "0", 1);
03276   test_sh("123456789.987654321", 1, "1234567900", 1);
03277   test_sh("123456789.987654321", 2, "12345678999", 1);
03278   test_sh("123456789.987654321", 4, "1234567899877", 1);
03279   test_sh("123456789.987654321", 8, "12345678998765432", 1);
03280   test_sh("123456789.987654321", 9, "123456789987654321", 0);
03281   test_sh("123456789.987654321", 10, "123456789.987654321", 2);
03282   test_sh("123456789.987654321", 0, "123456789.987654321", 0);
03283   a.len= sizeof(buf1)/sizeof(dec1);
03284 
03285   printf("==== decimal_actual_fraction ====\n");
03286   test_fr("1.123456789000000000", "1.123456789");
03287   test_fr("1.12345678000000000", "1.12345678");
03288   test_fr("1.1234567000000000", "1.1234567");
03289   test_fr("1.123456000000000", "1.123456");
03290   test_fr("1.12345000000000", "1.12345");
03291   test_fr("1.1234000000000", "1.1234");
03292   test_fr("1.123000000000", "1.123");
03293   test_fr("1.12000000000", "1.12");
03294   test_fr("1.1000000000", "1.1");
03295   test_fr("1.000000000", "1");
03296   test_fr("1.0", "1");
03297   test_fr("10000000000000000000.0", "10000000000000000000");
03298 
03299   return 0;
03300 }
03301 
03302 #endif