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