~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to strings/decimal.c

  • Committer: Stewart Smith
  • Date: 2008-07-13 06:56:15 UTC
  • mto: (210.1.1 drizzle)
  • mto: This revision was merged to the branch mainline in revision 211.
  • Revision ID: stewart@flamingspork.com-20080713065615-vzok75kgnnviokl9
Move MD5() into a UDF

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
 
16
#line 18 "decimal.c"
 
17
 
16
18
/*
17
19
=======================================================================
18
20
  NOTE: this library implements SQL standard "exact numeric" type
97
99
      implementation-defined.
98
100
*/
99
101
 
100
 
#include "config.h"
101
 
 
102
 
#include "drizzled/definitions.h"
103
 
#include "drizzled/internal/m_string.h"
104
 
#include "drizzled/charset_info.h"
105
 
#include "drizzled/decimal.h"
106
 
 
107
 
#include <plugin/myisam/myisampack.h>
108
 
#include <drizzled/util/test.h>
109
 
 
110
 
#ifdef HAVE_ALLOCA_H
111
 
#include <alloca.h>
112
 
#endif
113
 
 
114
 
#include <algorithm>
115
 
#include <time.h>
116
 
#include "drizzled/current_session.h"
117
 
#include "drizzled/error.h"
118
 
#include "drizzled/field.h"
119
 
#include "drizzled/internal/my_sys.h"
120
 
 
121
 
using namespace std;
122
 
 
123
 
namespace drizzled
124
 
{
125
 
/**
126
 
  report result of decimal operation.
127
 
 
128
 
  @param result  decimal library return code (E_DEC_* see include/decimal.h)
129
 
 
130
 
  @todo
131
 
    Fix error messages
132
 
 
133
 
  @return
134
 
    result
135
 
*/
136
 
 
137
 
int decimal_operation_results(int result)
138
 
{
139
 
  switch (result) {
140
 
  case E_DEC_OK:
141
 
    break;
142
 
  case E_DEC_TRUNCATED:
143
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
144
 
                        ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED),
145
 
                        "", (long)-1);
146
 
    break;
147
 
  case E_DEC_OVERFLOW:
148
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
149
 
                        ER_TRUNCATED_WRONG_VALUE,
150
 
                        ER(ER_TRUNCATED_WRONG_VALUE),
151
 
                        "DECIMAL", "");
152
 
    break;
153
 
  case E_DEC_DIV_ZERO:
154
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
155
 
                        ER_DIVISION_BY_ZERO, ER(ER_DIVISION_BY_ZERO));
156
 
    break;
157
 
  case E_DEC_BAD_NUM:
158
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
159
 
                        ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
160
 
                        ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
161
 
                        "decimal", "", "", (long)-1);
162
 
    break;
163
 
  case E_DEC_OOM:
164
 
    my_error(ER_OUT_OF_RESOURCES, MYF(0));
165
 
    break;
166
 
  default:
167
 
    assert(0);
168
 
  }
169
 
  return result;
170
 
}
171
 
 
172
 
 
173
 
/**
174
 
  @brief Converting decimal to string
175
 
 
176
 
  @details Convert given my_decimal to String; allocate buffer as needed.
177
 
 
178
 
  @param[in]   mask        what problems to warn on (mask of E_DEC_* values)
179
 
  @param[in]   d           the decimal to print
180
 
  @param[in]   fixed_prec  overall number of digits if ZEROFILL, 0 otherwise
181
 
  @param[in]   fixed_dec   number of decimal places (if fixed_prec != 0)
182
 
  @param[in]   filler      what char to pad with (ZEROFILL et al.)
183
 
  @param[out]  *str        where to store the resulting string
184
 
 
185
 
  @return error coce
186
 
    @retval E_DEC_OK
187
 
    @retval E_DEC_TRUNCATED
188
 
    @retval E_DEC_OVERFLOW
189
 
    @retval E_DEC_OOM
190
 
*/
191
 
 
192
 
int my_decimal2string(uint32_t mask, const my_decimal *d,
193
 
                      uint32_t fixed_prec, uint32_t fixed_dec,
194
 
                      char filler, String *str)
195
 
{
196
 
  /*
197
 
    Calculate the size of the string: For DECIMAL(a,b), fixed_prec==a
198
 
    holds true iff the type is also ZEROFILL, which in turn implies
199
 
    UNSIGNED. Hence the buffer for a ZEROFILLed value is the length
200
 
    the user requested, plus one for a possible decimal point, plus
201
 
    one if the user only wanted decimal places, but we force a leading
202
 
    zero on them. Because the type is implicitly UNSIGNED, we do not
203
 
    need to reserve a character for the sign. For all other cases,
204
 
    fixed_prec will be 0, and my_decimal_string_length() will be called
205
 
    instead to calculate the required size of the buffer.
206
 
  */
207
 
  int length= (fixed_prec
208
 
               ? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1)
209
 
               : my_decimal_string_length(d));
210
 
  int result;
211
 
  if (str->alloc(length))
212
 
    return check_result(mask, E_DEC_OOM);
213
 
  result= decimal2string((decimal_t*) d, (char*) str->ptr(),
214
 
                         &length, (int)fixed_prec, fixed_dec,
215
 
                         filler);
216
 
  str->length(length);
217
 
  return check_result(mask, result);
218
 
}
219
 
 
220
 
 
221
 
/*
222
 
  Convert from decimal to binary representation
223
 
 
224
 
  SYNOPSIS
225
 
    my_decimal2binary()
226
 
    mask        error processing mask
227
 
    d           number for conversion
228
 
    bin         pointer to buffer where to write result
229
 
    prec        overall number of decimal digits
230
 
    scale       number of decimal digits after decimal point
231
 
 
232
 
  NOTE
233
 
    Before conversion we round number if it need but produce truncation
234
 
    error in this case
235
 
 
236
 
  RETURN
237
 
    E_DEC_OK
238
 
    E_DEC_TRUNCATED
239
 
    E_DEC_OVERFLOW
240
 
*/
241
 
 
242
 
int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
243
 
                      int scale)
244
 
{
245
 
  int err1= E_DEC_OK, err2;
246
 
  my_decimal rounded;
247
 
  my_decimal2decimal(d, &rounded);
248
 
  rounded.frac= decimal_actual_fraction(&rounded);
249
 
  if (scale < rounded.frac)
250
 
  {
251
 
    err1= E_DEC_TRUNCATED;
252
 
    /* decimal_round can return only E_DEC_TRUNCATED */
253
 
    decimal_round(&rounded, &rounded, scale, HALF_UP);
254
 
  }
255
 
  err2= decimal2bin(&rounded, bin, prec, scale);
256
 
  if (!err2)
257
 
    err2= err1;
258
 
  return check_result(mask, err2);
259
 
}
260
 
 
261
 
 
262
 
/*
263
 
  Convert string for decimal when string can be in some multibyte charset
264
 
 
265
 
  SYNOPSIS
266
 
    str2my_decimal()
267
 
    mask            error processing mask
268
 
    from            string to process
269
 
    length          length of given string
270
 
    charset         charset of given string
271
 
    decimal_value   buffer for result storing
272
 
 
273
 
  RESULT
274
 
    E_DEC_OK
275
 
    E_DEC_TRUNCATED
276
 
    E_DEC_OVERFLOW
277
 
    E_DEC_BAD_NUM
278
 
    E_DEC_OOM
279
 
*/
280
 
 
281
 
int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
282
 
                   const CHARSET_INFO * charset, my_decimal *decimal_value)
283
 
{
284
 
  char *end, *from_end;
285
 
  int err;
286
 
  char buff[STRING_BUFFER_USUAL_SIZE];
287
 
  String tmp(buff, sizeof(buff), &my_charset_bin);
288
 
  if (charset->mbminlen > 1)
289
 
  {
290
 
    uint32_t dummy_errors;
291
 
    tmp.copy(from, length, charset, &my_charset_utf8_general_ci, &dummy_errors);
292
 
    from= tmp.ptr();
293
 
    length=  tmp.length();
294
 
    charset= &my_charset_bin;
295
 
  }
296
 
  from_end= end= (char*) from+length;
297
 
  err= string2decimal((char *)from, (decimal_t*) decimal_value, &end);
298
 
  if (end != from_end && !err)
299
 
  {
300
 
    /* Give warning if there is something other than end space */
301
 
    for ( ; end < from_end; end++)
302
 
    {
303
 
      if (!my_isspace(&my_charset_utf8_general_ci, *end))
304
 
      {
305
 
        err= E_DEC_TRUNCATED;
306
 
        break;
307
 
      }
308
 
    }
309
 
  }
310
 
  check_result_and_overflow(mask, err, decimal_value);
311
 
  return err;
312
 
}
313
 
 
314
 
 
315
 
my_decimal *date2my_decimal(DRIZZLE_TIME *ltime, my_decimal *dec)
316
 
{
317
 
  int64_t date;
318
 
  date = (ltime->year*100L + ltime->month)*100L + ltime->day;
319
 
  if (ltime->time_type > DRIZZLE_TIMESTAMP_DATE)
320
 
    date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second;
321
 
  if (int2my_decimal(E_DEC_FATAL_ERROR, date, false, dec))
322
 
    return dec;
323
 
  if (ltime->second_part)
324
 
  {
325
 
    dec->buf[(dec->intg-1) / 9 + 1]= ltime->second_part * 1000;
326
 
    dec->frac= 6;
327
 
  }
328
 
  return dec;
329
 
}
330
 
 
331
 
 
332
 
void my_decimal_trim(uint32_t *precision, uint32_t *scale)
333
 
{
334
 
  if (!(*precision) && !(*scale))
335
 
  {
336
 
    *precision= 10;
337
 
    *scale= 0;
338
 
    return;
339
 
  }
340
 
}
341
 
 
 
102
#include <my_global.h>
 
103
#include <m_ctype.h>
 
104
#include <myisampack.h>
 
105
#include <my_sys.h> /* for my_alloca */
 
106
#include <m_string.h>
 
107
#include <decimal.h>
342
108
 
343
109
/*
344
110
  Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
356
122
        not in bytes
357
123
*/
358
124
typedef decimal_digit_t dec1;
359
 
typedef int64_t      dec2;
 
125
typedef longlong      dec2;
360
126
 
361
127
#define DIG_PER_DEC1 9
362
128
#define DIG_MASK     100000000
363
129
#define DIG_BASE     1000000000
364
130
#define DIG_MAX      (DIG_BASE-1)
 
131
#define DIG_BASE2    ((dec2)DIG_BASE * (dec2)DIG_BASE)
365
132
#define ROUND_UP(X)  (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
366
133
static const dec1 powers10[DIG_PER_DEC1+1]={
367
134
  1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
372
139
  999999900, 999999990 };
373
140
 
374
141
#ifdef HAVE_purify
375
 
#define sanity(d) assert((d)->len > 0)
 
142
#define sanity(d) DBUG_ASSERT((d)->len > 0)
376
143
#else
377
 
#define sanity(d) assert((d)->len >0 && ((d)->buf[0] | \
 
144
#define sanity(d) DBUG_ASSERT((d)->len >0 && ((d)->buf[0] | \
378
145
                              (d)->buf[(d)->len-1] | 1))
379
146
#endif
380
147
 
403
170
        do                                                              \
404
171
        {                                                               \
405
172
          dec1 a=(from1)+(from2)+(carry);                               \
406
 
          assert((carry) <= 1);                                    \
 
173
          DBUG_ASSERT((carry) <= 1);                                    \
407
174
          if (((carry)= a >= DIG_BASE)) /* no division here! */         \
408
175
            a-=DIG_BASE;                                                \
409
176
          (to)=a;                                                       \
446
213
          (to)=a;                                                       \
447
214
        } while(0)
448
215
 
449
 
/**
450
 
  Swap the contents of two variables.
451
 
 */
452
 
#define swap_variables(TYPE, a, b) \
453
 
  do {                             \
454
 
    TYPE dummy;                    \
455
 
    dummy= a;                      \
456
 
    a= b;                          \
457
 
    b= dummy;                      \
458
 
  } while (0)
459
 
 
460
 
 
461
 
 
462
216
/*
463
217
  Get maximum value for given precision and scale
464
218
 
473
227
{
474
228
  int intpart;
475
229
  dec1 *buf= to->buf;
476
 
  assert(precision && precision >= frac);
 
230
  DBUG_ASSERT(precision && precision >= frac);
477
231
 
478
232
  to->sign= 0;
479
233
  if ((intpart= to->intg= (precision - frac)))
480
234
  {
481
 
    const int firstdigits= intpart % DIG_PER_DEC1;
 
235
    int firstdigits= intpart % DIG_PER_DEC1;
482
236
    if (firstdigits)
483
237
      *buf++= powers10[firstdigits] - 1; /* get 9 99 999 ... */
484
238
    for(intpart/= DIG_PER_DEC1; intpart; intpart--)
487
241
 
488
242
  if ((to->frac= frac))
489
243
  {
490
 
    const int lastdigits= frac % DIG_PER_DEC1;
 
244
    int lastdigits= frac % DIG_PER_DEC1;
491
245
    for(frac/= DIG_PER_DEC1; frac; frac--)
492
246
      *buf++= DIG_MAX;
493
247
    if (lastdigits)
496
250
}
497
251
 
498
252
 
499
 
static dec1 *remove_leading_zeroes(const decimal_t *from, int *intg_result)
 
253
static dec1 *remove_leading_zeroes(decimal_t *from, int *intg_result)
500
254
{
501
255
  int intg= from->intg, i;
502
256
  dec1 *buf0= from->buf;
510
264
  if (intg > 0)
511
265
  {
512
266
    for (i= (intg - 1) % DIG_PER_DEC1; *buf0 < powers10[i--]; intg--) ;
513
 
    assert(intg > 0);
 
267
    DBUG_ASSERT(intg > 0);
514
268
  }
515
269
  else
516
270
    intg=0;
572
326
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
573
327
*/
574
328
 
575
 
int decimal2string(const decimal_t *from, char *to, int *to_len,
 
329
int decimal2string(decimal_t *from, char *to, int *to_len,
576
330
                   int fixed_precision, int fixed_decimals,
577
331
                   char filler)
578
332
{
584
338
  char *s=to;
585
339
  dec1 *buf, *buf0=from->buf, tmp;
586
340
 
587
 
  assert(*to_len >= 2+from->sign);
 
341
  DBUG_ASSERT(*to_len >= 2+from->sign);
588
342
 
589
343
  /* removing leading zeroes */
590
344
  buf0= remove_leading_zeroes(from, &intg);
644
398
      for (i=min(frac, DIG_PER_DEC1); i; i--)
645
399
      {
646
400
        dec1 y=x/DIG_MASK;
647
 
        *s1++='0'+(unsigned char)y;
 
401
        *s1++='0'+(uchar)y;
648
402
        x-=y*DIG_MASK;
649
403
        x*=10;
650
404
      }
667
421
      for (i=min(intg, DIG_PER_DEC1); i; i--)
668
422
      {
669
423
        dec1 y=x/10;
670
 
        *--s='0'+(unsigned char)(x-y*10);
 
424
        *--s='0'+(uchar)(x-y*10);
671
425
        x=y;
672
426
      }
673
427
    }
762
516
  dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
763
517
  dec1 *end= dec->buf + ROUND_UP(last) - 1;
764
518
  int c_shift= DIG_PER_DEC1 - shift;
765
 
  assert(from >= dec->buf);
766
 
  assert(end < dec->buf + dec->len);
 
519
  DBUG_ASSERT(from >= dec->buf);
 
520
  DBUG_ASSERT(end < dec->buf + dec->len);
767
521
  if (beg % DIG_PER_DEC1 < shift)
768
522
    *(from - 1)= (*from) / powers10[c_shift];
769
523
  for(; from < end; from++)
792
546
  dec1 *from= dec->buf + ROUND_UP(last) - 1;
793
547
  dec1 *end= dec->buf + ROUND_UP(beg + 1) - 1;
794
548
  int c_shift= DIG_PER_DEC1 - shift;
795
 
  assert(from < dec->buf + dec->len);
796
 
  assert(end >= dec->buf);
 
549
  DBUG_ASSERT(from < dec->buf + dec->len);
 
550
  DBUG_ASSERT(end >= dec->buf);
797
551
  if (DIG_PER_DEC1 - ((last - 1) % DIG_PER_DEC1 + 1) < shift)
798
552
    *(from + 1)= (*from % powers10[shift]) * powers10[c_shift];
799
553
  for(; from > end; from--)
901
655
        result
902
656
      */
903
657
      do_left= l_mini_shift <= beg;
904
 
      assert(do_left || (dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
 
658
      DBUG_ASSERT(do_left || (dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
905
659
    }
906
660
    else
907
661
    {
909
663
      l_mini_shift= DIG_PER_DEC1 - r_mini_shift;
910
664
      /* see comment above */
911
665
      do_left= !((dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
912
 
      assert(!do_left || l_mini_shift <= beg);
 
666
      DBUG_ASSERT(!do_left || l_mini_shift <= beg);
913
667
    }
914
668
    if (do_left)
915
669
    {
949
703
      d_shift= new_front / DIG_PER_DEC1;
950
704
      to= dec->buf + (ROUND_UP(beg + 1) - 1 - d_shift);
951
705
      barier= dec->buf + (ROUND_UP(end) - 1 - d_shift);
952
 
      assert(to >= dec->buf);
953
 
      assert(barier + d_shift < dec->buf + dec->len);
 
706
      DBUG_ASSERT(to >= dec->buf);
 
707
      DBUG_ASSERT(barier + d_shift < dec->buf + dec->len);
954
708
      for(; to <= barier; to++)
955
709
        *to= *(to + d_shift);
956
710
      for(barier+= d_shift; to <= barier; to++)
963
717
      d_shift= (1 - new_front) / DIG_PER_DEC1;
964
718
      to= dec->buf + ROUND_UP(end) - 1 + d_shift;
965
719
      barier= dec->buf + ROUND_UP(beg + 1) - 1 + d_shift;
966
 
      assert(to < dec->buf + dec->len);
967
 
      assert(barier - d_shift >= dec->buf);
 
720
      DBUG_ASSERT(to < dec->buf + dec->len);
 
721
      DBUG_ASSERT(barier - d_shift >= dec->buf);
968
722
      for(; to >= barier; to--)
969
723
        *to= *(to - d_shift);
970
724
      for(barier-= d_shift; to >= barier; to--)
983
737
  */
984
738
  beg= ROUND_UP(beg + 1) - 1;
985
739
  end= ROUND_UP(end) - 1;
986
 
  assert(new_point >= 0);
987
 
 
 
740
  DBUG_ASSERT(new_point >= 0);
 
741
  
988
742
  /* We don't want negative new_point below */
989
743
  if (new_point != 0)
990
744
    new_point= ROUND_UP(new_point) - 1;
1030
784
*/
1031
785
 
1032
786
int
1033
 
internal_str2dec(char *from, decimal_t *to, char **end, bool fixed)
 
787
internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed)
1034
788
{
1035
 
  char *s= from, *s1;
1036
 
  char *end_of_string = *end;
1037
 
  char *endp;
 
789
  const char *s= from, *s1, *endp, *end_of_string= *end;
1038
790
  int i, intg, frac, error, intg1, frac1;
1039
791
  dec1 x,*buf;
1040
792
  sanity(to);
1041
793
 
1042
794
  error= E_DEC_BAD_NUM;                         /* In case of bad number */
1043
 
  while (s < end_of_string && my_isspace(&my_charset_utf8_general_ci, *s))
 
795
  while (s < end_of_string && my_isspace(&my_charset_latin1, *s))
1044
796
    s++;
1045
797
  if (s == end_of_string)
1046
798
    goto fatal_error;
1051
803
    s++;
1052
804
 
1053
805
  s1=s;
1054
 
  while (s < end_of_string && my_isdigit(&my_charset_utf8_general_ci, *s))
 
806
  while (s < end_of_string && my_isdigit(&my_charset_latin1, *s))
1055
807
    s++;
1056
808
  intg= (int) (s-s1);
1057
809
  if (s < end_of_string && *s=='.')
1058
810
  {
1059
811
    endp= s+1;
1060
 
    while (endp < end_of_string && my_isdigit(&my_charset_utf8_general_ci, *endp))
 
812
    while (endp < end_of_string && my_isdigit(&my_charset_latin1, *endp))
1061
813
      endp++;
1062
814
    frac= (int) (endp - s - 1);
1063
815
  }
1067
819
    endp= s;
1068
820
  }
1069
821
 
1070
 
  *end= endp;
 
822
  *end= (char*) endp;
1071
823
 
1072
824
  if (frac+intg == 0)
1073
825
    goto fatal_error;
1145
897
  if (endp+1 < end_of_string && (*endp == 'e' || *endp == 'E'))
1146
898
  {
1147
899
    int str_error;
1148
 
    const int64_t exponent= internal::my_strtoll10(endp+1, (char**) &end_of_string,
1149
 
                                                   &str_error);
 
900
    longlong exponent= my_strtoll10(endp+1, (char**) &end_of_string,
 
901
                                    &str_error);
1150
902
 
1151
903
    if (end_of_string != endp +1)               /* If at least one digit */
1152
904
    {
1190
942
    E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1191
943
*/
1192
944
 
1193
 
int decimal2double(const decimal_t *from, double *to)
 
945
int decimal2double(decimal_t *from, double *to)
1194
946
{
1195
947
  char strbuf[FLOATING_POINT_BUFFER], *end;
1196
948
  int len= sizeof(strbuf);
1198
950
 
1199
951
  rc = decimal2string(from, strbuf, &len, 0, 0, 0);
1200
952
  end= strbuf + len;
 
953
  
 
954
  DBUG_PRINT("info", ("interm.: %s", strbuf));
1201
955
 
1202
 
  *to= internal::my_strtod(strbuf, &end, &error);
 
956
  *to= my_strtod(strbuf, &end, &error);
 
957
             
 
958
  DBUG_PRINT("info", ("result: %f (%lx)", *to, *(ulong *)to));
1203
959
 
1204
960
  return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
1205
961
}
1216
972
    E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1217
973
*/
1218
974
 
1219
 
int double2decimal(const double from, decimal_t *to)
 
975
int double2decimal(double from, decimal_t *to)
1220
976
{
1221
977
  char buff[FLOATING_POINT_BUFFER], *end;
1222
978
  int res;
1223
 
  end= buff + internal::my_gcvt(from,
1224
 
                                internal::MY_GCVT_ARG_DOUBLE,
1225
 
                                sizeof(buff) - 1, buff, NULL);
 
979
  DBUG_ENTER("double2decimal");
 
980
  end= buff + my_gcvt(from, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
1226
981
  res= string2decimal(buff, to, &end);
1227
 
  return(res);
 
982
  DBUG_PRINT("exit", ("res: %d", res));
 
983
  DBUG_RETURN(res);
1228
984
}
1229
985
 
1230
986
 
1231
 
static int ull2dec(uint64_t from, decimal_t *to)
 
987
static int ull2dec(ulonglong from, decimal_t *to)
1232
988
{
1233
989
  int intg1, error=E_DEC_OK;
1234
 
  uint64_t x=from;
 
990
  ulonglong x=from;
1235
991
  dec1 *buf;
1236
992
 
1237
993
  sanity(to);
1247
1003
 
1248
1004
  for (buf=to->buf+intg1; intg1; intg1--)
1249
1005
  {
1250
 
    uint64_t y=x/DIG_BASE;
 
1006
    ulonglong y=x/DIG_BASE;
1251
1007
    *--buf=(dec1)(x-y*DIG_BASE);
1252
1008
    x=y;
1253
1009
  }
1254
1010
  return error;
1255
1011
}
1256
1012
 
1257
 
int uint64_t2decimal(const uint64_t from, decimal_t *to)
 
1013
int ulonglong2decimal(ulonglong from, decimal_t *to)
1258
1014
{
1259
1015
  to->sign=0;
1260
1016
  return ull2dec(from, to);
1261
1017
}
1262
1018
 
1263
 
int int64_t2decimal(const int64_t from, decimal_t *to)
 
1019
int longlong2decimal(longlong from, decimal_t *to)
1264
1020
{
1265
1021
  if ((to->sign= from < 0))
1266
1022
    return ull2dec(-from, to);
1267
1023
  return ull2dec(from, to);
1268
1024
}
1269
1025
 
1270
 
int decimal2uint64_t(const decimal_t *from, uint64_t *to)
 
1026
int decimal2ulonglong(decimal_t *from, ulonglong *to)
1271
1027
{
1272
1028
  dec1 *buf=from->buf;
1273
 
  uint64_t x=0;
 
1029
  ulonglong x=0;
1274
1030
  int intg, frac;
1275
1031
 
1276
1032
  if (from->sign)
1281
1037
 
1282
1038
  for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1283
1039
  {
1284
 
    uint64_t y=x;
 
1040
    ulonglong y=x;
1285
1041
    x=x*DIG_BASE + *buf++;
1286
 
    if (unlikely(y > ((uint64_t) UINT64_MAX/DIG_BASE) || x < y))
 
1042
    if (unlikely(y > ((ulonglong) ULONGLONG_MAX/DIG_BASE) || x < y))
1287
1043
    {
1288
 
      *to=UINT64_MAX;
 
1044
      *to=ULONGLONG_MAX;
1289
1045
      return E_DEC_OVERFLOW;
1290
1046
    }
1291
1047
  }
1296
1052
  return E_DEC_OK;
1297
1053
}
1298
1054
 
1299
 
int decimal2int64_t(const decimal_t *from, int64_t *to)
 
1055
int decimal2longlong(decimal_t *from, longlong *to)
1300
1056
{
1301
1057
  dec1 *buf=from->buf;
1302
 
  int64_t x=0;
 
1058
  longlong x=0;
1303
1059
  int intg, frac;
1304
1060
 
1305
1061
  for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1306
1062
  {
1307
 
    int64_t y=x;
 
1063
    longlong y=x;
1308
1064
    /*
1309
1065
      Attention: trick!
1310
1066
      we're calculating -|from| instead of |from| here
1311
 
      because |INT64_MIN| > INT64_MAX
 
1067
      because |LONGLONG_MIN| > LONGLONG_MAX
1312
1068
      so we can convert -9223372036854775808 correctly
1313
1069
    */
1314
1070
    x=x*DIG_BASE - *buf++;
1315
 
    if (unlikely(y < (INT64_MIN/DIG_BASE) || x > y))
 
1071
    if (unlikely(y < (LONGLONG_MIN/DIG_BASE) || x > y))
1316
1072
    {
1317
1073
      /*
1318
1074
        the decimal is bigger than any possible integer
1319
1075
        return border integer depending on the sign
1320
1076
      */
1321
 
      *to= from->sign ? INT64_MIN : INT64_MAX;
 
1077
      *to= from->sign ? LONGLONG_MIN : LONGLONG_MAX;
1322
1078
      return E_DEC_OVERFLOW;
1323
1079
    }
1324
1080
  }
1325
1081
  /* boundary case: 9223372036854775808 */
1326
 
  if (unlikely(from->sign==0 && x == INT64_MIN))
 
1082
  if (unlikely(from->sign==0 && x == LONGLONG_MIN))
1327
1083
  {
1328
 
    *to= INT64_MAX;
 
1084
    *to= LONGLONG_MAX;
1329
1085
    return E_DEC_OVERFLOW;
1330
1086
  }
1331
1087
 
1415
1171
 
1416
1172
                7E F2 04 37 2D FB 2D
1417
1173
*/
1418
 
int decimal2bin(const decimal_t *from, unsigned char *to, int precision, int frac)
 
1174
int decimal2bin(decimal_t *from, uchar *to, int precision, int frac)
1419
1175
{
1420
1176
  dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
1421
1177
  int error=E_DEC_OK, intg=precision-frac,
1431
1187
      fsize1=frac1*sizeof(dec1)+dig2bytes[frac1x];
1432
1188
  const int orig_isize0= isize0;
1433
1189
  const int orig_fsize0= fsize0;
1434
 
  unsigned char *orig_to= to;
 
1190
  uchar *orig_to= to;
1435
1191
 
1436
1192
  buf1= remove_leading_zeroes(from, &from_intg);
1437
1193
 
1487
1243
      case 2: mi_int2store(to, x); break;
1488
1244
      case 3: mi_int3store(to, x); break;
1489
1245
      case 4: mi_int4store(to, x); break;
1490
 
      default: assert(0);
 
1246
      default: DBUG_ASSERT(0);
1491
1247
    }
1492
1248
    to+=i;
1493
1249
  }
1496
1252
  for (stop1=buf1+intg1+frac1; buf1 < stop1; to+=sizeof(dec1))
1497
1253
  {
1498
1254
    dec1 x=*buf1++ ^ mask;
1499
 
    assert(sizeof(dec1) == 4);
 
1255
    DBUG_ASSERT(sizeof(dec1) == 4);
1500
1256
    mi_int4store(to, x);
1501
1257
  }
1502
1258
 
1515
1271
      case 2: mi_int2store(to, x); break;
1516
1272
      case 3: mi_int3store(to, x); break;
1517
1273
      case 4: mi_int4store(to, x); break;
1518
 
      default: assert(0);
 
1274
      default: DBUG_ASSERT(0);
1519
1275
    }
1520
1276
    to+=i;
1521
1277
  }
1522
1278
  if (fsize0 > fsize1)
1523
1279
  {
1524
 
    unsigned char *to_end= orig_to + orig_fsize0 + orig_isize0;
 
1280
    uchar *to_end= orig_to + orig_fsize0 + orig_isize0;
1525
1281
 
1526
1282
    while (fsize0-- > fsize1 && to < to_end)
1527
 
      *to++= (unsigned char)mask;
 
1283
      *to++= (uchar)mask;
1528
1284
  }
1529
1285
  orig_to[0]^= 0x80;
1530
1286
 
1531
1287
  /* Check that we have written the whole decimal and nothing more */
1532
 
  assert(to == orig_to + orig_fsize0 + orig_isize0);
 
1288
  DBUG_ASSERT(to == orig_to + orig_fsize0 + orig_isize0);
1533
1289
  return error;
1534
1290
}
1535
1291
 
1550
1306
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1551
1307
*/
1552
1308
 
1553
 
int bin2decimal(const unsigned char *from, decimal_t *to, int precision, int scale)
 
1309
int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale)
1554
1310
{
1555
1311
  int error=E_DEC_OK, intg=precision-scale,
1556
1312
      intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1557
1313
      intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1,
1558
1314
      intg1=intg0+(intg0x>0), frac1=frac0+(frac0x>0);
1559
1315
  dec1 *buf=to->buf, mask=(*from & 0x80) ? 0 : -1;
1560
 
  const unsigned char *stop;
1561
 
  unsigned char *d_copy;
 
1316
  const uchar *stop;
 
1317
  uchar *d_copy;
1562
1318
  int bin_size= decimal_bin_size(precision, scale);
1563
1319
 
1564
1320
  sanity(to);
1565
 
  d_copy= (unsigned char*) alloca(bin_size);
 
1321
  d_copy= (uchar*) my_alloca(bin_size);
1566
1322
  memcpy(d_copy, from, bin_size);
1567
1323
  d_copy[0]^= 0x80;
1568
1324
  from= d_copy;
1597
1353
      case 2: x=mi_sint2korr(from); break;
1598
1354
      case 3: x=mi_sint3korr(from); break;
1599
1355
      case 4: x=mi_sint4korr(from); break;
1600
 
      default: assert(0);
 
1356
      default: DBUG_ASSERT(0);
1601
1357
    }
1602
1358
    from+=i;
1603
1359
    *buf=x ^ mask;
1604
 
    if (((uint64_t)*buf) >= (uint64_t) powers10[intg0x+1])
 
1360
    if (((ulonglong)*buf) >= (ulonglong) powers10[intg0x+1])
1605
1361
      goto err;
1606
1362
    if (buf > to->buf || *buf != 0)
1607
1363
      buf++;
1610
1366
  }
1611
1367
  for (stop=from+intg0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1612
1368
  {
1613
 
    assert(sizeof(dec1) == 4);
 
1369
    DBUG_ASSERT(sizeof(dec1) == 4);
1614
1370
    *buf=mi_sint4korr(from) ^ mask;
1615
 
    if (((uint32_t)*buf) > DIG_MAX)
 
1371
    if (((uint32)*buf) > DIG_MAX)
1616
1372
      goto err;
1617
1373
    if (buf > to->buf || *buf != 0)
1618
1374
      buf++;
1619
1375
    else
1620
1376
      to->intg-=DIG_PER_DEC1;
1621
1377
  }
1622
 
  assert(to->intg >=0);
 
1378
  DBUG_ASSERT(to->intg >=0);
1623
1379
  for (stop=from+frac0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1624
1380
  {
1625
 
    assert(sizeof(dec1) == 4);
 
1381
    DBUG_ASSERT(sizeof(dec1) == 4);
1626
1382
    *buf=mi_sint4korr(from) ^ mask;
1627
 
    if (((uint32_t)*buf) > DIG_MAX)
 
1383
    if (((uint32)*buf) > DIG_MAX)
1628
1384
      goto err;
1629
1385
    buf++;
1630
1386
  }
1638
1394
      case 2: x=mi_sint2korr(from); break;
1639
1395
      case 3: x=mi_sint3korr(from); break;
1640
1396
      case 4: x=mi_sint4korr(from); break;
1641
 
      default: assert(0);
 
1397
      default: DBUG_ASSERT(0);
1642
1398
    }
1643
1399
    *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
1644
 
    if (((uint32_t)*buf) > DIG_MAX)
 
1400
    if (((uint32)*buf) > DIG_MAX)
1645
1401
      goto err;
1646
1402
    buf++;
1647
1403
  }
 
1404
  my_afree(d_copy);
1648
1405
  return error;
1649
1406
 
1650
1407
err:
 
1408
  my_afree(d_copy);
1651
1409
  decimal_make_zero(((decimal_t*) to));
1652
1410
  return(E_DEC_BAD_NUM);
1653
1411
}
1654
1412
 
1655
1413
/*
 
1414
  Returns the size of array to hold a decimal with given precision and scale
 
1415
 
 
1416
  RETURN VALUE
 
1417
    size in dec1
 
1418
    (multiply by sizeof(dec1) to get the size if bytes)
 
1419
*/
 
1420
 
 
1421
int decimal_size(int precision, int scale)
 
1422
{
 
1423
  DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
 
1424
  return ROUND_UP(precision-scale)+ROUND_UP(scale);
 
1425
}
 
1426
 
 
1427
/*
1656
1428
  Returns the size of array to hold a binary representation of a decimal
1657
1429
 
1658
1430
  RETURN VALUE
1665
1437
      intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1666
1438
      intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1;
1667
1439
 
1668
 
  assert(scale >= 0 && precision > 0 && scale <= precision);
 
1440
  DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
1669
1441
  return intg0*sizeof(dec1)+dig2bytes[intg0x]+
1670
1442
         frac0*sizeof(dec1)+dig2bytes[frac0x];
1671
1443
}
1689
1461
*/
1690
1462
 
1691
1463
int
1692
 
decimal_round(const decimal_t *from, decimal_t *to, int scale,
 
1464
decimal_round(decimal_t *from, decimal_t *to, int scale,
1693
1465
              decimal_round_mode mode)
1694
1466
{
1695
1467
  int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
1708
1480
  case CEILING:         round_digit= from->sign ? 10 : 0; break;
1709
1481
  case FLOOR:           round_digit= from->sign ? 0 : 10; break;
1710
1482
  case TRUNCATE:        round_digit=10; break;
1711
 
  default: assert(0);
 
1483
  default: DBUG_ASSERT(0);
1712
1484
  }
1713
1485
 
1714
1486
  if (unlikely(frac0+intg0 > len))
1756
1528
  buf1+=intg0+frac0-1;
1757
1529
  if (scale == frac0*DIG_PER_DEC1)
1758
1530
  {
1759
 
    int do_inc= false;
1760
 
    assert(frac0+intg0 >= 0);
 
1531
    int do_inc= FALSE;
 
1532
    DBUG_ASSERT(frac0+intg0 >= 0);
1761
1533
    switch (round_digit) {
1762
1534
    case 0:
1763
1535
    {
1766
1538
      {
1767
1539
        if (*p0)
1768
1540
        {
1769
 
          do_inc= true;
 
1541
          do_inc= TRUE;
1770
1542
          break;
1771
1543
        }
1772
1544
      }
1799
1571
  {
1800
1572
    /* TODO - fix this code as it won't work for CEILING mode */
1801
1573
    int pos=frac0*DIG_PER_DEC1-scale-1;
1802
 
    assert(frac0+intg0 > 0);
 
1574
    DBUG_ASSERT(frac0+intg0 > 0);
1803
1575
    x=*buf1 / powers10[pos];
1804
1576
    y=x % 10;
1805
1577
    if (y > round_digit ||
1881
1653
  return error;
1882
1654
}
1883
1655
 
1884
 
static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
1656
/*
 
1657
  Returns the size of the result of the operation
 
1658
 
 
1659
  SYNOPSIS
 
1660
    decimal_result_size()
 
1661
      from1   - operand of the unary operation or first operand of the
 
1662
                binary operation
 
1663
      from2   - second operand of the binary operation
 
1664
      op      - operation. one char '+', '-', '*', '/' are allowed
 
1665
                others may be added later
 
1666
      param   - extra param to the operation. unused for '+', '-', '*'
 
1667
                scale increment for '/'
 
1668
 
 
1669
  NOTE
 
1670
    returned valued may be larger than the actual buffer requred
 
1671
    in the operation, as decimal_result_size, by design, operates on
 
1672
    precision/scale values only and not on the actual decimal number
 
1673
 
 
1674
  RETURN VALUE
 
1675
    size of to->buf array in dec1 elements. to get size in bytes
 
1676
    multiply by sizeof(dec1)
 
1677
*/
 
1678
 
 
1679
int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, int param)
 
1680
{
 
1681
  switch (op) {
 
1682
  case '-':
 
1683
    return ROUND_UP(max(from1->intg, from2->intg)) +
 
1684
           ROUND_UP(max(from1->frac, from2->frac));
 
1685
  case '+':
 
1686
    return ROUND_UP(max(from1->intg, from2->intg)+1) +
 
1687
           ROUND_UP(max(from1->frac, from2->frac));
 
1688
  case '*':
 
1689
    return ROUND_UP(from1->intg+from2->intg)+
 
1690
           ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
 
1691
  case '/':
 
1692
    return ROUND_UP(from1->intg+from2->intg+1+from1->frac+from2->frac+param);
 
1693
  default: DBUG_ASSERT(0);
 
1694
  }
 
1695
  return -1; /* shut up the warning */
 
1696
}
 
1697
 
 
1698
static int do_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
1885
1699
{
1886
1700
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1887
1701
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1921
1735
    set_if_smaller(intg2, intg0);
1922
1736
  }
1923
1737
 
1924
 
  /* part 1 - cmax(frac) ... cmin(frac) */
 
1738
  /* part 1 - max(frac) ... min (frac) */
1925
1739
  if (frac1 > frac2)
1926
1740
  {
1927
1741
    buf1=from1->buf+intg1+frac1;
1939
1753
  while (buf1 > stop)
1940
1754
    *--buf0=*--buf1;
1941
1755
 
1942
 
  /* part 2 - cmin(frac) ... cmin(intg) */
 
1756
  /* part 2 - min(frac) ... min(intg) */
1943
1757
  carry=0;
1944
1758
  while (buf1 > stop2)
1945
1759
  {
1946
1760
    ADD(*--buf0, *--buf1, *--buf2, carry);
1947
1761
  }
1948
1762
 
1949
 
  /* part 3 - cmin(intg) ... cmax(intg) */
 
1763
  /* part 3 - min(intg) ... max(intg) */
1950
1764
  buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
1951
1765
                        ((stop=from2->buf)+intg2-intg1) ;
1952
1766
  while (buf1 > stop)
1956
1770
 
1957
1771
  if (unlikely(carry))
1958
1772
    *--buf0=1;
1959
 
  assert(buf0 == to->buf || buf0 == to->buf+1);
 
1773
  DBUG_ASSERT(buf0 == to->buf || buf0 == to->buf+1);
1960
1774
 
1961
1775
  return error;
1962
1776
}
1963
1777
 
1964
1778
/* to=from1-from2.
1965
1779
   if to==0, return -1/0/+1 - the result of the comparison */
1966
 
static int do_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
1780
static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
1967
1781
{
1968
1782
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1969
1783
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
2032
1846
  /* ensure that always from1 > from2 (and intg1 >= intg2) */
2033
1847
  if (carry)
2034
1848
  {
2035
 
    swap_variables(const decimal_t *,from1, from2);
 
1849
    swap_variables(decimal_t *,from1,from1);
2036
1850
    swap_variables(dec1 *,start1, start2);
2037
1851
    swap_variables(int,intg1,intg2);
2038
1852
    swap_variables(int,frac1,frac2);
2053
1867
  }
2054
1868
  carry=0;
2055
1869
 
2056
 
  /* part 1 - cmax(frac) ... cmin(frac) */
 
1870
  /* part 1 - max(frac) ... min (frac) */
2057
1871
  if (frac1 > frac2)
2058
1872
  {
2059
1873
    buf1=start1+intg1+frac1;
2077
1891
    }
2078
1892
  }
2079
1893
 
2080
 
  /* part 2 - cmin(frac) ... intg2 */
 
1894
  /* part 2 - min(frac) ... intg2 */
2081
1895
  while (buf2 > start2)
2082
1896
  {
2083
1897
    SUB(*--buf0, *--buf1, *--buf2, carry);
2098
1912
  return error;
2099
1913
}
2100
1914
 
2101
 
int decimal_intg(const decimal_t *from)
 
1915
int decimal_intg(decimal_t *from)
2102
1916
{
2103
1917
  int res;
2104
1918
  dec1 *tmp_res;
2106
1920
  return res;
2107
1921
}
2108
1922
 
2109
 
int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
1923
int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
2110
1924
{
2111
1925
  if (likely(from1->sign == from2->sign))
2112
1926
    return do_add(from1, from2, to);
2113
1927
  return do_sub(from1, from2, to);
2114
1928
}
2115
1929
 
2116
 
int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
1930
int decimal_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
2117
1931
{
2118
1932
  if (likely(from1->sign == from2->sign))
2119
1933
    return do_sub(from1, from2, to);
2120
1934
  return do_add(from1, from2, to);
2121
1935
}
2122
1936
 
2123
 
int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
 
1937
int decimal_cmp(decimal_t *from1, decimal_t *from2)
2124
1938
{
2125
1939
  if (likely(from1->sign == from2->sign))
2126
1940
    return do_sub(from1, from2, 0);
2127
1941
  return from1->sign > from2->sign ? -1 : 1;
2128
1942
}
2129
1943
 
2130
 
int decimal_is_zero(const decimal_t *from)
 
1944
int decimal_is_zero(decimal_t *from)
2131
1945
{
2132
1946
  dec1 *buf1=from->buf,
2133
1947
       *end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
2158
1972
    XXX if this library is to be used with huge numbers of thousands of
2159
1973
    digits, fast multiplication must be implemented.
2160
1974
*/
2161
 
int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
1975
int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to)
2162
1976
{
2163
1977
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
2164
1978
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
2201
2015
  stop1=buf1-intg1;
2202
2016
  stop2=buf2-intg2;
2203
2017
 
2204
 
  memset(to->buf, 0, (intg0+frac0)*sizeof(dec1));
 
2018
  bzero(to->buf, (intg0+frac0)*sizeof(dec1));
2205
2019
 
2206
2020
  for (buf1+=frac1-1; buf1 >= stop1; buf1--, start0--)
2207
2021
  {
2234
2048
  {
2235
2049
    dec1 *buf= to->buf;
2236
2050
    dec1 *end= to->buf + intg0 + frac0;
2237
 
    assert(buf != end);
 
2051
    DBUG_ASSERT(buf != end);
2238
2052
    for (;;)
2239
2053
    {
2240
2054
      if (*buf)
2274
2088
  changed to malloc (or at least fallback to malloc if alloca() fails)
2275
2089
  but then, decimal_mul() should be rewritten too :(
2276
2090
*/
2277
 
static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
 
2091
static int do_div_mod(decimal_t *from1, decimal_t *from2,
2278
2092
                       decimal_t *to, decimal_t *mod, int scale_incr)
2279
2093
{
2280
2094
  int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2300
2114
  if (prec2 <= 0) /* short-circuit everything: from2 == 0 */
2301
2115
    return E_DEC_DIV_ZERO;
2302
2116
  for (i= (prec2 - 1) % DIG_PER_DEC1; *buf2 < powers10[i--]; prec2--) ;
2303
 
  assert(prec2 > 0);
 
2117
  DBUG_ASSERT(prec2 > 0);
2304
2118
 
2305
2119
  i=((prec1-1) % DIG_PER_DEC1)+1;
2306
2120
  while (prec1 > 0 && *buf1 == 0)
2315
2129
    return E_DEC_OK;
2316
2130
  }
2317
2131
  for (i=(prec1-1) % DIG_PER_DEC1; *buf1 < powers10[i--]; prec1--) ;
2318
 
  assert(prec1 > 0);
 
2132
  DBUG_ASSERT(prec1 > 0);
2319
2133
 
2320
2134
  /* let's fix scale_incr, taking into account frac1,frac2 increase */
2321
2135
  if ((scale_incr-= frac1 - from1->frac + frac2 - from2->frac) < 0)
2333
2147
  {
2334
2148
    /* we're calculating N1 % N2.
2335
2149
       The result will have
2336
 
         frac=cmax(frac1, frac2), as for subtraction
 
2150
         frac=max(frac1, frac2), as for subtraction
2337
2151
         intg=intg2
2338
2152
    */
2339
2153
    to->sign=from1->sign;
2366
2180
 
2367
2181
  len1=(i=ROUND_UP(prec1))+ROUND_UP(2*frac2+scale_incr+1) + 1;
2368
2182
  set_if_bigger(len1, 3);
2369
 
  if (!(tmp1=(dec1 *)alloca(len1*sizeof(dec1))))
 
2183
  if (!(tmp1=(dec1 *)my_alloca(len1*sizeof(dec1))))
2370
2184
    return E_DEC_OOM;
2371
2185
  memcpy(tmp1, buf1, i*sizeof(dec1));
2372
 
  memset(tmp1+i, 0, (len1-i)*sizeof(dec1));
 
2186
  bzero(tmp1+i, (len1-i)*sizeof(dec1));
2373
2187
 
2374
2188
  start1=tmp1;
2375
2189
  stop1=start1+len1;
2420
2234
          guess--;
2421
2235
        if (unlikely(start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y))
2422
2236
          guess--;
2423
 
        assert(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y);
 
2237
        DBUG_ASSERT(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y);
2424
2238
      }
2425
2239
 
2426
2240
      /* D4: multiply and subtract */
2427
2241
      buf2=stop2;
2428
2242
      buf1=start1+len2;
2429
 
      assert(buf1 < stop1);
 
2243
      DBUG_ASSERT(buf1 < stop1);
2430
2244
      for (carry=0; buf2 > start2; buf1--)
2431
2245
      {
2432
2246
        dec1 hi, lo;
2461
2275
    /*
2462
2276
      now the result is in tmp1, it has
2463
2277
        intg=prec1-frac1
2464
 
        frac=cmax(frac1, frac2)=to->frac
 
2278
        frac=max(frac1, frac2)=to->frac
2465
2279
    */
2466
2280
    if (dcarry)
2467
2281
      *--start1=dcarry;
2497
2311
        error=E_DEC_OVERFLOW;
2498
2312
        goto done;
2499
2313
      }
2500
 
      assert(intg0 <= ROUND_UP(from2->intg));
 
2314
      DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
2501
2315
      stop1=start1+frac0+intg0;
2502
2316
      to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
2503
2317
    }
2508
2322
      to->frac=frac0*DIG_PER_DEC1;
2509
2323
        error=E_DEC_TRUNCATED;
2510
2324
    }
2511
 
    assert(buf0 + (stop1 - start1) <= to->buf + to->len);
 
2325
    DBUG_ASSERT(buf0 + (stop1 - start1) <= to->buf + to->len);
2512
2326
    while (start1 < stop1)
2513
2327
        *buf0++=*start1++;
2514
2328
  }
2515
2329
done:
 
2330
  my_afree(tmp1);
2516
2331
  return error;
2517
2332
}
2518
2333
 
2533
2348
*/
2534
2349
 
2535
2350
int
2536
 
decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, int scale_incr)
 
2351
decimal_div(decimal_t *from1, decimal_t *from2, decimal_t *to, int scale_incr)
2537
2352
{
2538
2353
  return do_div_mod(from1, from2, to, 0, scale_incr);
2539
2354
}
2565
2380
   thus, there's no requirement for M or N to be integers
2566
2381
*/
2567
2382
 
2568
 
int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
2383
int decimal_mod(decimal_t *from1, decimal_t *from2, decimal_t *to)
2569
2384
{
2570
2385
  return do_div_mod(from1, from2, 0, to, 0);
2571
2386
}
2572
2387
 
2573
 
} /* namespace drizzled */
2574
 
 
2575
2388
#ifdef MAIN
2576
2389
 
2577
2390
int full= 0;
2654
2467
{
2655
2468
  char s1[100], *end;
2656
2469
  int res;
2657
 
  snprintf(s1, sizeof(s1), "'%s'", s);
 
2470
  sprintf(s1, "'%s'", s);
2658
2471
  end= strend(s);
2659
2472
  printf("len=%2d %-30s => res=%d    ", a.len, s1,
2660
2473
         (res= string2decimal(s, &a, &end)));
2668
2481
  double x;
2669
2482
  int res;
2670
2483
 
2671
 
  snprintf(s1, sizeof(s1), "'%s'", s);
 
2484
  sprintf(s1, "'%s'", s);
2672
2485
  end= strend(s);
2673
2486
  string2decimal(s, &a, &end);
2674
2487
  res=decimal2double(&a, &x);
2682
2495
  char s1[100], buf[100], *end;
2683
2496
  int res, i, size=decimal_bin_size(p, s);
2684
2497
 
2685
 
  snprintf(s1, sizeof(s1), "'%s'", str);
 
2498
  sprintf(s1, "'%s'", str);
2686
2499
  end= strend(str);
2687
2500
  string2decimal(str, &a, &end);
2688
2501
  res=decimal2bin(&a, buf, p, s);
2691
2504
  {
2692
2505
    printf("0x");
2693
2506
    for (i=0; i < size; i++)
2694
 
      printf("%02x", ((unsigned char *)buf)[i]);
 
2507
      printf("%02x", ((uchar *)buf)[i]);
2695
2508
  }
2696
2509
  res=bin2decimal(buf, &a, p, s);
2697
2510
  printf(" => res=%d ", res);
2709
2522
  printf("\n");
2710
2523
}
2711
2524
 
2712
 
void test_ull2d(uint64_t from, const char *orig, int ex)
 
2525
void test_ull2d(ulonglong from, const char *orig, int ex)
2713
2526
{
2714
2527
  char s[100];
2715
2528
  int res;
2716
2529
 
2717
 
  res=uint64_t2decimal(from, &a);
2718
 
  internal::int64_t10_to_str(from,s,10);
 
2530
  res=ulonglong2decimal(from, &a);
 
2531
  longlong10_to_str(from,s,10);
2719
2532
  printf("%-40s => res=%d    ", s, res);
2720
2533
  print_decimal(&a, orig, res, ex);
2721
2534
  printf("\n");
2722
2535
}
2723
2536
 
2724
 
void test_ll2d(int64_t from, const char *orig, int ex)
 
2537
void test_ll2d(longlong from, const char *orig, int ex)
2725
2538
{
2726
2539
  char s[100];
2727
2540
  int res;
2728
2541
 
2729
 
  res=int64_t2decimal(from, &a);
2730
 
  internal::int64_t10_to_str(from,s,-10);
 
2542
  res=longlong2decimal(from, &a);
 
2543
  longlong10_to_str(from,s,-10);
2731
2544
  printf("%-40s => res=%d    ", s, res);
2732
2545
  print_decimal(&a, orig, res, ex);
2733
2546
  printf("\n");
2736
2549
void test_d2ull(const char *s, const char *orig, int ex)
2737
2550
{
2738
2551
  char s1[100], *end;
2739
 
  uint64_t x;
 
2552
  ulonglong x;
2740
2553
  int res;
2741
2554
 
2742
2555
  end= strend(s);
2743
2556
  string2decimal(s, &a, &end);
2744
 
  res=decimal2uint64_t(&a, &x);
 
2557
  res=decimal2ulonglong(&a, &x);
2745
2558
  if (full) dump_decimal(&a);
2746
 
  internal::int64_t10_to_str(x,s1,10);
 
2559
  longlong10_to_str(x,s1,10);
2747
2560
  printf("%-40s => res=%d    %s\n", s, res, s1);
2748
2561
  check_result_code(res, ex);
2749
2562
  if (orig && strcmp(orig, s1))
2756
2569
void test_d2ll(const char *s, const char *orig, int ex)
2757
2570
{
2758
2571
  char s1[100], *end;
2759
 
  int64_t x;
 
2572
  longlong x;
2760
2573
  int res;
2761
2574
 
2762
2575
  end= strend(s);
2763
2576
  string2decimal(s, &a, &end);
2764
 
  res=decimal2int64_t(&a, &x);
 
2577
  res=decimal2longlong(&a, &x);
2765
2578
  if (full) dump_decimal(&a);
2766
 
  internal::int64_t10_to_str(x,s1,-10);
 
2579
  longlong10_to_str(x,s1,-10);
2767
2580
  printf("%-40s => res=%d    %s\n", s, res, s1);
2768
2581
  check_result_code(res, ex);
2769
2582
  if (orig && strcmp(orig, s1))
2777
2590
{
2778
2591
  char s[100], *end;
2779
2592
  int res;
2780
 
  snprintf(s, sizeof(s), "'%s' + '%s'", s1, s2);
 
2593
  sprintf(s, "'%s' + '%s'", s1, s2);
2781
2594
  end= strend(s1);
2782
2595
  string2decimal(s1, &a, &end);
2783
2596
  end= strend(s2);
2792
2605
{
2793
2606
  char s[100], *end;
2794
2607
  int res;
2795
 
  snprintf(s, sizeof(s), "'%s' - '%s'", s1, s2);
 
2608
  sprintf(s, "'%s' - '%s'", s1, s2);
2796
2609
  end= strend(s1);
2797
2610
  string2decimal(s1, &a, &end);
2798
2611
  end= strend(s2);
2807
2620
{
2808
2621
  char s[100], *end;
2809
2622
  int res;
2810
 
  snprintf(s, sizeof(s), "'%s' <=> '%s'", s1, s2);
 
2623
  sprintf(s, "'%s' <=> '%s'", s1, s2);
2811
2624
  end= strend(s1);
2812
2625
  string2decimal(s1, &a, &end);
2813
2626
  end= strend(s2);
2825
2638
{
2826
2639
  char s[100], *end;
2827
2640
  int res;
2828
 
  snprintf(s, sizeof(s), "'%s' * '%s'", s1, s2);
 
2641
  sprintf(s, "'%s' * '%s'", s1, s2);
2829
2642
  end= strend(s1);
2830
2643
  string2decimal(s1, &a, &end);
2831
2644
  end= strend(s2);
2840
2653
{
2841
2654
  char s[100], *end;
2842
2655
  int res;
2843
 
  snprintf(s, sizeof(s), "'%s' / '%s'", s1, s2);
 
2656
  sprintf(s, "'%s' / '%s'", s1, s2);
2844
2657
  end= strend(s1);
2845
2658
  string2decimal(s1, &a, &end);
2846
2659
  end= strend(s2);
2859
2672
{
2860
2673
  char s[100], *end;
2861
2674
  int res;
2862
 
  snprintf(s, sizeof(s), "'%s' %% '%s'", s1, s2);
 
2675
  sprintf(s, "'%s' %% '%s'", s1, s2);
2863
2676
  end= strend(s1);
2864
2677
  string2decimal(s1, &a, &end);
2865
2678
  end= strend(s2);
2882
2695
{
2883
2696
  char s[100], *end;
2884
2697
  int res;
2885
 
  snprintf(s, sizeof(s), "'%s', %d, %s", s1, n, round_mode[mode]);
 
2698
  sprintf(s, "'%s', %d, %s", s1, n, round_mode[mode]);
2886
2699
  end= strend(s1);
2887
2700
  string2decimal(s1, &a, &end);
2888
2701
  res=decimal_round(&a, &b, n, mode);
2895
2708
void test_mx(int precision, int frac, const char *orig)
2896
2709
{
2897
2710
  char s[100];
2898
 
  snprintf(s, sizeof(s), "%d, %d", precision, frac);
 
2711
  sprintf(s, "%d, %d", precision, frac);
2899
2712
  max_decimal(precision, frac, &a);
2900
2713
  printf("%-40s =>          ", s);
2901
2714
  print_decimal(&a, orig, 0, 0);
2911
2724
  int slen= sizeof(s2);
2912
2725
  int res;
2913
2726
 
2914
 
  snprintf(s, sizeof(s), filler ? "'%s', %d, %d, '%c'" : "'%s', %d, %d, '\\0'",
 
2727
  sprintf(s, filler ? "'%s', %d, %d, '%c'" : "'%s', %d, %d, '\\0'",
2915
2728
          s1, prec, dec, filler);
2916
2729
  end= strend(s1);
2917
2730
  string2decimal(s1, &a, &end);
2931
2744
{
2932
2745
  char s[100], *end;
2933
2746
  int res;
2934
 
  snprintf(s, sizeof(s), "'%s' %s %d", s1, ((shift < 0) ? ">>" : "<<"), abs(shift));
 
2747
  sprintf(s, "'%s' %s %d", s1, ((shift < 0) ? ">>" : "<<"), abs(shift));
2935
2748
  end= strend(s1);
2936
2749
  string2decimal(s1, &a, &end);
2937
2750
  res= decimal_shift(&a, shift);
2944
2757
void test_fr(const char *s1, const char *orig)
2945
2758
{
2946
2759
  char s[100], *end;
2947
 
  snprintf(s, sizeof(s), "'%s'", s1);
 
2760
  sprintf(s, "'%s'", s1);
2948
2761
  printf("%-40s =>          ", s);
2949
2762
  end= strend(s1);
2950
2763
  string2decimal(s1, &a, &end);
2996
2809
  test_f2d(0.00012345000098765, 0);
2997
2810
  test_f2d(1234500009876.5, 0);
2998
2811
 
2999
 
  printf("==== uint64_t2decimal ====\n");
 
2812
  printf("==== ulonglong2decimal ====\n");
3000
2813
  test_ull2d(12345ULL, "12345", 0);
3001
2814
  test_ull2d(0ULL, "0", 0);
3002
2815
  test_ull2d(18446744073709551615ULL, "18446744073709551615", 0);
3003
2816
 
3004
 
  printf("==== decimal2uint64_t ====\n");
 
2817
  printf("==== decimal2ulonglong ====\n");
3005
2818
  test_d2ull("12345", "12345", 0);
3006
2819
  test_d2ull("0", "0", 0);
3007
2820
  test_d2ull("18446744073709551615", "18446744073709551615", 0);
3010
2823
  test_d2ull("1.23", "1", 1);
3011
2824
  test_d2ull("9999999999999999999999999.000", "9999999999999999", 2);
3012
2825
 
3013
 
  printf("==== int64_t2decimal ====\n");
 
2826
  printf("==== longlong2decimal ====\n");
3014
2827
  test_ll2d(12345LL, "-12345", 0);
3015
2828
  test_ll2d(1LL, "-1", 0);
3016
2829
  test_ll2d(9223372036854775807LL, "-9223372036854775807", 0);
3017
2830
  test_ll2d(9223372036854775808ULL, "-9223372036854775808", 0);
3018
2831
 
3019
 
  printf("==== decimal2int64_t ====\n");
 
2832
  printf("==== decimal2longlong ====\n");
3020
2833
  test_d2ll("18446744073709551615", "18446744073", 2);
3021
2834
  test_d2ll("-1", "-1", 0);
3022
2835
  test_d2ll("-1.23", "-1", 1);