~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to strings/decimal.c

Removed/replaced DBUG symbols and standardized TRUE/FALSE

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
 
#include <alloca.h>
 
102
#include <my_global.h>
 
103
#include <m_ctype.h>
 
104
#include <myisampack.h>
 
105
#include <my_sys.h> /* for my_alloca */
102
106
#include <m_string.h>
103
 
#include <m_ctype.h>
104
 
#include <storage/myisam/myisampack.h>
105
 
#include <mystrings/decimal.h>
 
107
#include <decimal.h>
106
108
 
107
 
#include <drizzled/util/test.h>
108
109
/*
109
110
  Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
110
111
  So one variable of type decimal_digit_t is limited:
121
122
        not in bytes
122
123
*/
123
124
typedef decimal_digit_t dec1;
124
 
typedef int64_t      dec2;
 
125
typedef longlong      dec2;
125
126
 
126
127
#define DIG_PER_DEC1 9
127
128
#define DIG_MASK     100000000
128
129
#define DIG_BASE     1000000000
129
130
#define DIG_MAX      (DIG_BASE-1)
 
131
#define DIG_BASE2    ((dec2)DIG_BASE * (dec2)DIG_BASE)
130
132
#define ROUND_UP(X)  (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
131
133
static const dec1 powers10[DIG_PER_DEC1+1]={
132
134
  1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
137
139
  999999900, 999999990 };
138
140
 
139
141
#ifdef HAVE_purify
140
 
#define sanity(d) assert((d)->len > 0)
 
142
#define sanity(d) DBUG_ASSERT((d)->len > 0)
141
143
#else
142
 
#define sanity(d) assert((d)->len >0 && ((d)->buf[0] | \
 
144
#define sanity(d) DBUG_ASSERT((d)->len >0 && ((d)->buf[0] | \
143
145
                              (d)->buf[(d)->len-1] | 1))
144
146
#endif
145
147
 
168
170
        do                                                              \
169
171
        {                                                               \
170
172
          dec1 a=(from1)+(from2)+(carry);                               \
171
 
          assert((carry) <= 1);                                    \
 
173
          DBUG_ASSERT((carry) <= 1);                                    \
172
174
          if (((carry)= a >= DIG_BASE)) /* no division here! */         \
173
175
            a-=DIG_BASE;                                                \
174
176
          (to)=a;                                                       \
211
213
          (to)=a;                                                       \
212
214
        } while(0)
213
215
 
214
 
/**
215
 
  Swap the contents of two variables.
216
 
 */
217
 
#define swap_variables(TYPE, a, b) \
218
 
  do {                             \
219
 
    TYPE dummy;                    \
220
 
    dummy= a;                      \
221
 
    a= b;                          \
222
 
    b= dummy;                      \
223
 
  } while (0)
224
 
 
225
 
 
226
216
/*
227
217
  Get maximum value for given precision and scale
228
218
 
237
227
{
238
228
  int intpart;
239
229
  dec1 *buf= to->buf;
240
 
  assert(precision && precision >= frac);
 
230
  DBUG_ASSERT(precision && precision >= frac);
241
231
 
242
232
  to->sign= 0;
243
233
  if ((intpart= to->intg= (precision - frac)))
244
234
  {
245
 
    const int firstdigits= intpart % DIG_PER_DEC1;
 
235
    int firstdigits= intpart % DIG_PER_DEC1;
246
236
    if (firstdigits)
247
237
      *buf++= powers10[firstdigits] - 1; /* get 9 99 999 ... */
248
238
    for(intpart/= DIG_PER_DEC1; intpart; intpart--)
251
241
 
252
242
  if ((to->frac= frac))
253
243
  {
254
 
    const int lastdigits= frac % DIG_PER_DEC1;
 
244
    int lastdigits= frac % DIG_PER_DEC1;
255
245
    for(frac/= DIG_PER_DEC1; frac; frac--)
256
246
      *buf++= DIG_MAX;
257
247
    if (lastdigits)
274
264
  if (intg > 0)
275
265
  {
276
266
    for (i= (intg - 1) % DIG_PER_DEC1; *buf0 < powers10[i--]; intg--) ;
277
 
    assert(intg > 0);
 
267
    DBUG_ASSERT(intg > 0);
278
268
  }
279
269
  else
280
270
    intg=0;
348
338
  char *s=to;
349
339
  dec1 *buf, *buf0=from->buf, tmp;
350
340
 
351
 
  assert(*to_len >= 2+from->sign);
 
341
  DBUG_ASSERT(*to_len >= 2+from->sign);
352
342
 
353
343
  /* removing leading zeroes */
354
344
  buf0= remove_leading_zeroes(from, &intg);
405
395
    for (; frac>0; frac-=DIG_PER_DEC1)
406
396
    {
407
397
      dec1 x=*buf++;
408
 
      for (i=cmin(frac, DIG_PER_DEC1); i; i--)
 
398
      for (i=min(frac, DIG_PER_DEC1); i; i--)
409
399
      {
410
400
        dec1 y=x/DIG_MASK;
411
 
        *s1++='0'+(unsigned char)y;
 
401
        *s1++='0'+(uchar)y;
412
402
        x-=y*DIG_MASK;
413
403
        x*=10;
414
404
      }
428
418
    for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
429
419
    {
430
420
      dec1 x=*--buf;
431
 
      for (i=cmin(intg, DIG_PER_DEC1); i; i--)
 
421
      for (i=min(intg, DIG_PER_DEC1); i; i--)
432
422
      {
433
423
        dec1 y=x/10;
434
 
        *--s='0'+(unsigned char)(x-y*10);
 
424
        *--s='0'+(uchar)(x-y*10);
435
425
        x=y;
436
426
      }
437
427
    }
526
516
  dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
527
517
  dec1 *end= dec->buf + ROUND_UP(last) - 1;
528
518
  int c_shift= DIG_PER_DEC1 - shift;
529
 
  assert(from >= dec->buf);
530
 
  assert(end < dec->buf + dec->len);
 
519
  DBUG_ASSERT(from >= dec->buf);
 
520
  DBUG_ASSERT(end < dec->buf + dec->len);
531
521
  if (beg % DIG_PER_DEC1 < shift)
532
522
    *(from - 1)= (*from) / powers10[c_shift];
533
523
  for(; from < end; from++)
556
546
  dec1 *from= dec->buf + ROUND_UP(last) - 1;
557
547
  dec1 *end= dec->buf + ROUND_UP(beg + 1) - 1;
558
548
  int c_shift= DIG_PER_DEC1 - shift;
559
 
  assert(from < dec->buf + dec->len);
560
 
  assert(end >= dec->buf);
 
549
  DBUG_ASSERT(from < dec->buf + dec->len);
 
550
  DBUG_ASSERT(end >= dec->buf);
561
551
  if (DIG_PER_DEC1 - ((last - 1) % DIG_PER_DEC1 + 1) < shift)
562
552
    *(from + 1)= (*from % powers10[shift]) * powers10[c_shift];
563
553
  for(; from > end; from--)
665
655
        result
666
656
      */
667
657
      do_left= l_mini_shift <= beg;
668
 
      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);
669
659
    }
670
660
    else
671
661
    {
673
663
      l_mini_shift= DIG_PER_DEC1 - r_mini_shift;
674
664
      /* see comment above */
675
665
      do_left= !((dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
676
 
      assert(!do_left || l_mini_shift <= beg);
 
666
      DBUG_ASSERT(!do_left || l_mini_shift <= beg);
677
667
    }
678
668
    if (do_left)
679
669
    {
713
703
      d_shift= new_front / DIG_PER_DEC1;
714
704
      to= dec->buf + (ROUND_UP(beg + 1) - 1 - d_shift);
715
705
      barier= dec->buf + (ROUND_UP(end) - 1 - d_shift);
716
 
      assert(to >= dec->buf);
717
 
      assert(barier + d_shift < dec->buf + dec->len);
 
706
      DBUG_ASSERT(to >= dec->buf);
 
707
      DBUG_ASSERT(barier + d_shift < dec->buf + dec->len);
718
708
      for(; to <= barier; to++)
719
709
        *to= *(to + d_shift);
720
710
      for(barier+= d_shift; to <= barier; to++)
727
717
      d_shift= (1 - new_front) / DIG_PER_DEC1;
728
718
      to= dec->buf + ROUND_UP(end) - 1 + d_shift;
729
719
      barier= dec->buf + ROUND_UP(beg + 1) - 1 + d_shift;
730
 
      assert(to < dec->buf + dec->len);
731
 
      assert(barier - d_shift >= dec->buf);
 
720
      DBUG_ASSERT(to < dec->buf + dec->len);
 
721
      DBUG_ASSERT(barier - d_shift >= dec->buf);
732
722
      for(; to >= barier; to--)
733
723
        *to= *(to - d_shift);
734
724
      for(barier-= d_shift; to >= barier; to--)
747
737
  */
748
738
  beg= ROUND_UP(beg + 1) - 1;
749
739
  end= ROUND_UP(end) - 1;
750
 
  assert(new_point >= 0);
 
740
  DBUG_ASSERT(new_point >= 0);
751
741
  
752
742
  /* We don't want negative new_point below */
753
743
  if (new_point != 0)
794
784
*/
795
785
 
796
786
int
797
 
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)
798
788
{
799
 
  char *s= from, *s1;
800
 
  char *end_of_string = *end;
801
 
  char *endp;
 
789
  const char *s= from, *s1, *endp, *end_of_string= *end;
802
790
  int i, intg, frac, error, intg1, frac1;
803
791
  dec1 x,*buf;
804
792
  sanity(to);
805
793
 
806
794
  error= E_DEC_BAD_NUM;                         /* In case of bad number */
807
 
  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))
808
796
    s++;
809
797
  if (s == end_of_string)
810
798
    goto fatal_error;
815
803
    s++;
816
804
 
817
805
  s1=s;
818
 
  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))
819
807
    s++;
820
808
  intg= (int) (s-s1);
821
809
  if (s < end_of_string && *s=='.')
822
810
  {
823
811
    endp= s+1;
824
 
    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))
825
813
      endp++;
826
814
    frac= (int) (endp - s - 1);
827
815
  }
831
819
    endp= s;
832
820
  }
833
821
 
834
 
  *end= endp;
 
822
  *end= (char*) endp;
835
823
 
836
824
  if (frac+intg == 0)
837
825
    goto fatal_error;
909
897
  if (endp+1 < end_of_string && (*endp == 'e' || *endp == 'E'))
910
898
  {
911
899
    int str_error;
912
 
    const int64_t exponent= my_strtoll10(endp+1, (char**) &end_of_string,
 
900
    longlong exponent= my_strtoll10(endp+1, (char**) &end_of_string,
913
901
                                    &str_error);
914
902
 
915
903
    if (end_of_string != endp +1)               /* If at least one digit */
963
951
  rc = decimal2string(from, strbuf, &len, 0, 0, 0);
964
952
  end= strbuf + len;
965
953
  
 
954
  DBUG_PRINT("info", ("interm.: %s", strbuf));
 
955
 
966
956
  *to= my_strtod(strbuf, &end, &error);
967
957
             
 
958
  DBUG_PRINT("info", ("result: %f (%lx)", *to, *(ulong *)to));
 
959
 
968
960
  return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
969
961
}
970
962
 
984
976
{
985
977
  char buff[FLOATING_POINT_BUFFER], *end;
986
978
  int res;
 
979
  DBUG_ENTER("double2decimal");
987
980
  end= buff + my_gcvt(from, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
988
981
  res= string2decimal(buff, to, &end);
989
 
  return(res);
 
982
  DBUG_PRINT("exit", ("res: %d", res));
 
983
  DBUG_RETURN(res);
990
984
}
991
985
 
992
986
 
993
 
static int ull2dec(uint64_t from, decimal_t *to)
 
987
static int ull2dec(ulonglong from, decimal_t *to)
994
988
{
995
989
  int intg1, error=E_DEC_OK;
996
 
  uint64_t x=from;
 
990
  ulonglong x=from;
997
991
  dec1 *buf;
998
992
 
999
993
  sanity(to);
1009
1003
 
1010
1004
  for (buf=to->buf+intg1; intg1; intg1--)
1011
1005
  {
1012
 
    uint64_t y=x/DIG_BASE;
 
1006
    ulonglong y=x/DIG_BASE;
1013
1007
    *--buf=(dec1)(x-y*DIG_BASE);
1014
1008
    x=y;
1015
1009
  }
1016
1010
  return error;
1017
1011
}
1018
1012
 
1019
 
int uint64_t2decimal(uint64_t from, decimal_t *to)
 
1013
int ulonglong2decimal(ulonglong from, decimal_t *to)
1020
1014
{
1021
1015
  to->sign=0;
1022
1016
  return ull2dec(from, to);
1023
1017
}
1024
1018
 
1025
 
int int64_t2decimal(int64_t from, decimal_t *to)
 
1019
int longlong2decimal(longlong from, decimal_t *to)
1026
1020
{
1027
1021
  if ((to->sign= from < 0))
1028
1022
    return ull2dec(-from, to);
1029
1023
  return ull2dec(from, to);
1030
1024
}
1031
1025
 
1032
 
int decimal2uint64_t(decimal_t *from, uint64_t *to)
 
1026
int decimal2ulonglong(decimal_t *from, ulonglong *to)
1033
1027
{
1034
1028
  dec1 *buf=from->buf;
1035
 
  uint64_t x=0;
 
1029
  ulonglong x=0;
1036
1030
  int intg, frac;
1037
1031
 
1038
1032
  if (from->sign)
1043
1037
 
1044
1038
  for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1045
1039
  {
1046
 
    uint64_t y=x;
 
1040
    ulonglong y=x;
1047
1041
    x=x*DIG_BASE + *buf++;
1048
 
    if (unlikely(y > ((uint64_t) UINT64_MAX/DIG_BASE) || x < y))
 
1042
    if (unlikely(y > ((ulonglong) ULONGLONG_MAX/DIG_BASE) || x < y))
1049
1043
    {
1050
 
      *to=UINT64_MAX;
 
1044
      *to=ULONGLONG_MAX;
1051
1045
      return E_DEC_OVERFLOW;
1052
1046
    }
1053
1047
  }
1058
1052
  return E_DEC_OK;
1059
1053
}
1060
1054
 
1061
 
int decimal2int64_t(decimal_t *from, int64_t *to)
 
1055
int decimal2longlong(decimal_t *from, longlong *to)
1062
1056
{
1063
1057
  dec1 *buf=from->buf;
1064
 
  int64_t x=0;
 
1058
  longlong x=0;
1065
1059
  int intg, frac;
1066
1060
 
1067
1061
  for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1068
1062
  {
1069
 
    int64_t y=x;
 
1063
    longlong y=x;
1070
1064
    /*
1071
1065
      Attention: trick!
1072
1066
      we're calculating -|from| instead of |from| here
1073
 
      because |INT64_MIN| > INT64_MAX
 
1067
      because |LONGLONG_MIN| > LONGLONG_MAX
1074
1068
      so we can convert -9223372036854775808 correctly
1075
1069
    */
1076
1070
    x=x*DIG_BASE - *buf++;
1077
 
    if (unlikely(y < (INT64_MIN/DIG_BASE) || x > y))
 
1071
    if (unlikely(y < (LONGLONG_MIN/DIG_BASE) || x > y))
1078
1072
    {
1079
1073
      /*
1080
1074
        the decimal is bigger than any possible integer
1081
1075
        return border integer depending on the sign
1082
1076
      */
1083
 
      *to= from->sign ? INT64_MIN : INT64_MAX;
 
1077
      *to= from->sign ? LONGLONG_MIN : LONGLONG_MAX;
1084
1078
      return E_DEC_OVERFLOW;
1085
1079
    }
1086
1080
  }
1087
1081
  /* boundary case: 9223372036854775808 */
1088
 
  if (unlikely(from->sign==0 && x == INT64_MIN))
 
1082
  if (unlikely(from->sign==0 && x == LONGLONG_MIN))
1089
1083
  {
1090
 
    *to= INT64_MAX;
 
1084
    *to= LONGLONG_MAX;
1091
1085
    return E_DEC_OVERFLOW;
1092
1086
  }
1093
1087
 
1177
1171
 
1178
1172
                7E F2 04 37 2D FB 2D
1179
1173
*/
1180
 
int decimal2bin(decimal_t *from, unsigned char *to, int precision, int frac)
 
1174
int decimal2bin(decimal_t *from, uchar *to, int precision, int frac)
1181
1175
{
1182
1176
  dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
1183
1177
  int error=E_DEC_OK, intg=precision-frac,
1193
1187
      fsize1=frac1*sizeof(dec1)+dig2bytes[frac1x];
1194
1188
  const int orig_isize0= isize0;
1195
1189
  const int orig_fsize0= fsize0;
1196
 
  unsigned char *orig_to= to;
 
1190
  uchar *orig_to= to;
1197
1191
 
1198
1192
  buf1= remove_leading_zeroes(from, &from_intg);
1199
1193
 
1249
1243
      case 2: mi_int2store(to, x); break;
1250
1244
      case 3: mi_int3store(to, x); break;
1251
1245
      case 4: mi_int4store(to, x); break;
1252
 
      default: assert(0);
 
1246
      default: DBUG_ASSERT(0);
1253
1247
    }
1254
1248
    to+=i;
1255
1249
  }
1258
1252
  for (stop1=buf1+intg1+frac1; buf1 < stop1; to+=sizeof(dec1))
1259
1253
  {
1260
1254
    dec1 x=*buf1++ ^ mask;
1261
 
    assert(sizeof(dec1) == 4);
 
1255
    DBUG_ASSERT(sizeof(dec1) == 4);
1262
1256
    mi_int4store(to, x);
1263
1257
  }
1264
1258
 
1277
1271
      case 2: mi_int2store(to, x); break;
1278
1272
      case 3: mi_int3store(to, x); break;
1279
1273
      case 4: mi_int4store(to, x); break;
1280
 
      default: assert(0);
 
1274
      default: DBUG_ASSERT(0);
1281
1275
    }
1282
1276
    to+=i;
1283
1277
  }
1284
1278
  if (fsize0 > fsize1)
1285
1279
  {
1286
 
    unsigned char *to_end= orig_to + orig_fsize0 + orig_isize0;
 
1280
    uchar *to_end= orig_to + orig_fsize0 + orig_isize0;
1287
1281
 
1288
1282
    while (fsize0-- > fsize1 && to < to_end)
1289
 
      *to++= (unsigned char)mask;
 
1283
      *to++= (uchar)mask;
1290
1284
  }
1291
1285
  orig_to[0]^= 0x80;
1292
1286
 
1293
1287
  /* Check that we have written the whole decimal and nothing more */
1294
 
  assert(to == orig_to + orig_fsize0 + orig_isize0);
 
1288
  DBUG_ASSERT(to == orig_to + orig_fsize0 + orig_isize0);
1295
1289
  return error;
1296
1290
}
1297
1291
 
1312
1306
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1313
1307
*/
1314
1308
 
1315
 
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)
1316
1310
{
1317
1311
  int error=E_DEC_OK, intg=precision-scale,
1318
1312
      intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1319
1313
      intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1,
1320
1314
      intg1=intg0+(intg0x>0), frac1=frac0+(frac0x>0);
1321
1315
  dec1 *buf=to->buf, mask=(*from & 0x80) ? 0 : -1;
1322
 
  const unsigned char *stop;
1323
 
  unsigned char *d_copy;
 
1316
  const uchar *stop;
 
1317
  uchar *d_copy;
1324
1318
  int bin_size= decimal_bin_size(precision, scale);
1325
1319
 
1326
1320
  sanity(to);
1327
 
  d_copy= (unsigned char*) alloca(bin_size);
 
1321
  d_copy= (uchar*) my_alloca(bin_size);
1328
1322
  memcpy(d_copy, from, bin_size);
1329
1323
  d_copy[0]^= 0x80;
1330
1324
  from= d_copy;
1359
1353
      case 2: x=mi_sint2korr(from); break;
1360
1354
      case 3: x=mi_sint3korr(from); break;
1361
1355
      case 4: x=mi_sint4korr(from); break;
1362
 
      default: assert(0);
 
1356
      default: DBUG_ASSERT(0);
1363
1357
    }
1364
1358
    from+=i;
1365
1359
    *buf=x ^ mask;
1366
 
    if (((uint64_t)*buf) >= (uint64_t) powers10[intg0x+1])
 
1360
    if (((ulonglong)*buf) >= (ulonglong) powers10[intg0x+1])
1367
1361
      goto err;
1368
1362
    if (buf > to->buf || *buf != 0)
1369
1363
      buf++;
1372
1366
  }
1373
1367
  for (stop=from+intg0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1374
1368
  {
1375
 
    assert(sizeof(dec1) == 4);
 
1369
    DBUG_ASSERT(sizeof(dec1) == 4);
1376
1370
    *buf=mi_sint4korr(from) ^ mask;
1377
 
    if (((uint32_t)*buf) > DIG_MAX)
 
1371
    if (((uint32)*buf) > DIG_MAX)
1378
1372
      goto err;
1379
1373
    if (buf > to->buf || *buf != 0)
1380
1374
      buf++;
1381
1375
    else
1382
1376
      to->intg-=DIG_PER_DEC1;
1383
1377
  }
1384
 
  assert(to->intg >=0);
 
1378
  DBUG_ASSERT(to->intg >=0);
1385
1379
  for (stop=from+frac0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1386
1380
  {
1387
 
    assert(sizeof(dec1) == 4);
 
1381
    DBUG_ASSERT(sizeof(dec1) == 4);
1388
1382
    *buf=mi_sint4korr(from) ^ mask;
1389
 
    if (((uint32_t)*buf) > DIG_MAX)
 
1383
    if (((uint32)*buf) > DIG_MAX)
1390
1384
      goto err;
1391
1385
    buf++;
1392
1386
  }
1400
1394
      case 2: x=mi_sint2korr(from); break;
1401
1395
      case 3: x=mi_sint3korr(from); break;
1402
1396
      case 4: x=mi_sint4korr(from); break;
1403
 
      default: assert(0);
 
1397
      default: DBUG_ASSERT(0);
1404
1398
    }
1405
1399
    *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
1406
 
    if (((uint32_t)*buf) > DIG_MAX)
 
1400
    if (((uint32)*buf) > DIG_MAX)
1407
1401
      goto err;
1408
1402
    buf++;
1409
1403
  }
 
1404
  my_afree(d_copy);
1410
1405
  return error;
1411
1406
 
1412
1407
err:
 
1408
  my_afree(d_copy);
1413
1409
  decimal_make_zero(((decimal_t*) to));
1414
1410
  return(E_DEC_BAD_NUM);
1415
1411
}
1424
1420
 
1425
1421
int decimal_size(int precision, int scale)
1426
1422
{
1427
 
  assert(scale >= 0 && precision > 0 && scale <= precision);
 
1423
  DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
1428
1424
  return ROUND_UP(precision-scale)+ROUND_UP(scale);
1429
1425
}
1430
1426
 
1441
1437
      intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1442
1438
      intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1;
1443
1439
 
1444
 
  assert(scale >= 0 && precision > 0 && scale <= precision);
 
1440
  DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
1445
1441
  return intg0*sizeof(dec1)+dig2bytes[intg0x]+
1446
1442
         frac0*sizeof(dec1)+dig2bytes[frac0x];
1447
1443
}
1484
1480
  case CEILING:         round_digit= from->sign ? 10 : 0; break;
1485
1481
  case FLOOR:           round_digit= from->sign ? 0 : 10; break;
1486
1482
  case TRUNCATE:        round_digit=10; break;
1487
 
  default: assert(0);
 
1483
  default: DBUG_ASSERT(0);
1488
1484
  }
1489
1485
 
1490
1486
  if (unlikely(frac0+intg0 > len))
1502
1498
 
1503
1499
  if (to != from || intg1>intg0)
1504
1500
  {
1505
 
    dec1 *p0= buf0+intg0+cmax(frac1, frac0);
1506
 
    dec1 *p1= buf1+intg1+cmax(frac1, frac0);
 
1501
    dec1 *p0= buf0+intg0+max(frac1, frac0);
 
1502
    dec1 *p1= buf1+intg1+max(frac1, frac0);
1507
1503
 
1508
1504
    while (buf0 < p0)
1509
1505
      *(--p1) = *(--p0);
1514
1510
    buf0=to->buf;
1515
1511
    buf1=to->buf;
1516
1512
    to->sign=from->sign;
1517
 
    to->intg=cmin(intg0, len)*DIG_PER_DEC1;
 
1513
    to->intg=min(intg0, len)*DIG_PER_DEC1;
1518
1514
  }
1519
1515
 
1520
1516
  if (frac0 > frac1)
1532
1528
  buf1+=intg0+frac0-1;
1533
1529
  if (scale == frac0*DIG_PER_DEC1)
1534
1530
  {
1535
 
    int do_inc= false;
1536
 
    assert(frac0+intg0 >= 0);
 
1531
    int do_inc= FALSE;
 
1532
    DBUG_ASSERT(frac0+intg0 >= 0);
1537
1533
    switch (round_digit) {
1538
1534
    case 0:
1539
1535
    {
1542
1538
      {
1543
1539
        if (*p0)
1544
1540
        {
1545
 
          do_inc= true;
 
1541
          do_inc= TRUE;
1546
1542
          break;
1547
1543
        }
1548
1544
      }
1575
1571
  {
1576
1572
    /* TODO - fix this code as it won't work for CEILING mode */
1577
1573
    int pos=frac0*DIG_PER_DEC1-scale-1;
1578
 
    assert(frac0+intg0 > 0);
 
1574
    DBUG_ASSERT(frac0+intg0 > 0);
1579
1575
    x=*buf1 / powers10[pos];
1580
1576
    y=x % 10;
1581
1577
    if (y > round_digit ||
1616
1612
        scale=frac0*DIG_PER_DEC1;
1617
1613
        error=E_DEC_TRUNCATED; /* XXX */
1618
1614
      }
1619
 
      for (buf1=to->buf+intg0+cmax(frac0,0); buf1 > to->buf; buf1--)
 
1615
      for (buf1=to->buf+intg0+max(frac0,0); buf1 > to->buf; buf1--)
1620
1616
      {
1621
1617
        buf1[0]=buf1[-1];
1622
1618
      }
1635
1631
        /* making 'zero' with the proper scale */
1636
1632
        dec1 *p0= to->buf + frac0 + 1;
1637
1633
        to->intg=1;
1638
 
        to->frac= cmax(scale, 0);
 
1634
        to->frac= max(scale, 0);
1639
1635
        to->sign= 0;
1640
1636
        for (buf1= to->buf; buf1<p0; buf1++)
1641
1637
          *buf1= 0;
1684
1680
{
1685
1681
  switch (op) {
1686
1682
  case '-':
1687
 
    return ROUND_UP(cmax(from1->intg, from2->intg)) +
1688
 
           ROUND_UP(cmax(from1->frac, from2->frac));
 
1683
    return ROUND_UP(max(from1->intg, from2->intg)) +
 
1684
           ROUND_UP(max(from1->frac, from2->frac));
1689
1685
  case '+':
1690
 
    return ROUND_UP(cmax(from1->intg, from2->intg)+1) +
1691
 
           ROUND_UP(cmax(from1->frac, from2->frac));
 
1686
    return ROUND_UP(max(from1->intg, from2->intg)+1) +
 
1687
           ROUND_UP(max(from1->frac, from2->frac));
1692
1688
  case '*':
1693
1689
    return ROUND_UP(from1->intg+from2->intg)+
1694
1690
           ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
1695
1691
  case '/':
1696
1692
    return ROUND_UP(from1->intg+from2->intg+1+from1->frac+from2->frac+param);
1697
 
  default: assert(0);
 
1693
  default: DBUG_ASSERT(0);
1698
1694
  }
1699
1695
  return -1; /* shut up the warning */
1700
1696
}
1703
1699
{
1704
1700
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1705
1701
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1706
 
      frac0=cmax(frac1, frac2), intg0=cmax(intg1, intg2), error;
 
1702
      frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
1707
1703
  dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
1708
1704
 
1709
1705
  sanity(to);
1728
1724
  buf0=to->buf+intg0+frac0;
1729
1725
 
1730
1726
  to->sign=from1->sign;
1731
 
  to->frac=cmax(from1->frac, from2->frac);
 
1727
  to->frac=max(from1->frac, from2->frac);
1732
1728
  to->intg=intg0*DIG_PER_DEC1;
1733
1729
  if (unlikely(error))
1734
1730
  {
1739
1735
    set_if_smaller(intg2, intg0);
1740
1736
  }
1741
1737
 
1742
 
  /* part 1 - cmax(frac) ... cmin(frac) */
 
1738
  /* part 1 - max(frac) ... min (frac) */
1743
1739
  if (frac1 > frac2)
1744
1740
  {
1745
1741
    buf1=from1->buf+intg1+frac1;
1757
1753
  while (buf1 > stop)
1758
1754
    *--buf0=*--buf1;
1759
1755
 
1760
 
  /* part 2 - cmin(frac) ... cmin(intg) */
 
1756
  /* part 2 - min(frac) ... min(intg) */
1761
1757
  carry=0;
1762
1758
  while (buf1 > stop2)
1763
1759
  {
1764
1760
    ADD(*--buf0, *--buf1, *--buf2, carry);
1765
1761
  }
1766
1762
 
1767
 
  /* part 3 - cmin(intg) ... cmax(intg) */
 
1763
  /* part 3 - min(intg) ... max(intg) */
1768
1764
  buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
1769
1765
                        ((stop=from2->buf)+intg2-intg1) ;
1770
1766
  while (buf1 > stop)
1774
1770
 
1775
1771
  if (unlikely(carry))
1776
1772
    *--buf0=1;
1777
 
  assert(buf0 == to->buf || buf0 == to->buf+1);
 
1773
  DBUG_ASSERT(buf0 == to->buf || buf0 == to->buf+1);
1778
1774
 
1779
1775
  return error;
1780
1776
}
1785
1781
{
1786
1782
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1787
1783
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
1788
 
  int frac0=cmax(frac1, frac2), error;
 
1784
  int frac0=max(frac1, frac2), error;
1789
1785
  dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
1790
1786
 
1791
1787
  /* let carry:=1 if from2 > from1 */
1860
1856
  FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
1861
1857
  buf0=to->buf+intg1+frac0;
1862
1858
 
1863
 
  to->frac=cmax(from1->frac, from2->frac);
 
1859
  to->frac=max(from1->frac, from2->frac);
1864
1860
  to->intg=intg1*DIG_PER_DEC1;
1865
1861
  if (unlikely(error))
1866
1862
  {
1871
1867
  }
1872
1868
  carry=0;
1873
1869
 
1874
 
  /* part 1 - cmax(frac) ... cmin(frac) */
 
1870
  /* part 1 - max(frac) ... min (frac) */
1875
1871
  if (frac1 > frac2)
1876
1872
  {
1877
1873
    buf1=start1+intg1+frac1;
1895
1891
    }
1896
1892
  }
1897
1893
 
1898
 
  /* part 2 - cmin(frac) ... intg2 */
 
1894
  /* part 2 - min(frac) ... intg2 */
1899
1895
  while (buf2 > start2)
1900
1896
  {
1901
1897
    SUB(*--buf0, *--buf1, *--buf2, carry);
2019
2015
  stop1=buf1-intg1;
2020
2016
  stop2=buf2-intg2;
2021
2017
 
2022
 
  memset(to->buf, 0, (intg0+frac0)*sizeof(dec1));
 
2018
  bzero(to->buf, (intg0+frac0)*sizeof(dec1));
2023
2019
 
2024
2020
  for (buf1+=frac1-1; buf1 >= stop1; buf1--, start0--)
2025
2021
  {
2052
2048
  {
2053
2049
    dec1 *buf= to->buf;
2054
2050
    dec1 *end= to->buf + intg0 + frac0;
2055
 
    assert(buf != end);
 
2051
    DBUG_ASSERT(buf != end);
2056
2052
    for (;;)
2057
2053
    {
2058
2054
      if (*buf)
2118
2114
  if (prec2 <= 0) /* short-circuit everything: from2 == 0 */
2119
2115
    return E_DEC_DIV_ZERO;
2120
2116
  for (i= (prec2 - 1) % DIG_PER_DEC1; *buf2 < powers10[i--]; prec2--) ;
2121
 
  assert(prec2 > 0);
 
2117
  DBUG_ASSERT(prec2 > 0);
2122
2118
 
2123
2119
  i=((prec1-1) % DIG_PER_DEC1)+1;
2124
2120
  while (prec1 > 0 && *buf1 == 0)
2133
2129
    return E_DEC_OK;
2134
2130
  }
2135
2131
  for (i=(prec1-1) % DIG_PER_DEC1; *buf1 < powers10[i--]; prec1--) ;
2136
 
  assert(prec1 > 0);
 
2132
  DBUG_ASSERT(prec1 > 0);
2137
2133
 
2138
2134
  /* let's fix scale_incr, taking into account frac1,frac2 increase */
2139
2135
  if ((scale_incr-= frac1 - from1->frac + frac2 - from2->frac) < 0)
2151
2147
  {
2152
2148
    /* we're calculating N1 % N2.
2153
2149
       The result will have
2154
 
         frac=cmax(frac1, frac2), as for subtraction
 
2150
         frac=max(frac1, frac2), as for subtraction
2155
2151
         intg=intg2
2156
2152
    */
2157
2153
    to->sign=from1->sign;
2158
 
    to->frac=cmax(from1->frac, from2->frac);
 
2154
    to->frac=max(from1->frac, from2->frac);
2159
2155
    frac0=0;
2160
2156
  }
2161
2157
  else
2184
2180
 
2185
2181
  len1=(i=ROUND_UP(prec1))+ROUND_UP(2*frac2+scale_incr+1) + 1;
2186
2182
  set_if_bigger(len1, 3);
2187
 
  if (!(tmp1=(dec1 *)alloca(len1*sizeof(dec1))))
 
2183
  if (!(tmp1=(dec1 *)my_alloca(len1*sizeof(dec1))))
2188
2184
    return E_DEC_OOM;
2189
2185
  memcpy(tmp1, buf1, i*sizeof(dec1));
2190
 
  memset(tmp1+i, 0, (len1-i)*sizeof(dec1));
 
2186
  bzero(tmp1+i, (len1-i)*sizeof(dec1));
2191
2187
 
2192
2188
  start1=tmp1;
2193
2189
  stop1=start1+len1;
2238
2234
          guess--;
2239
2235
        if (unlikely(start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y))
2240
2236
          guess--;
2241
 
        assert(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y);
 
2237
        DBUG_ASSERT(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y);
2242
2238
      }
2243
2239
 
2244
2240
      /* D4: multiply and subtract */
2245
2241
      buf2=stop2;
2246
2242
      buf1=start1+len2;
2247
 
      assert(buf1 < stop1);
 
2243
      DBUG_ASSERT(buf1 < stop1);
2248
2244
      for (carry=0; buf2 > start2; buf1--)
2249
2245
      {
2250
2246
        dec1 hi, lo;
2279
2275
    /*
2280
2276
      now the result is in tmp1, it has
2281
2277
        intg=prec1-frac1
2282
 
        frac=cmax(frac1, frac2)=to->frac
 
2278
        frac=max(frac1, frac2)=to->frac
2283
2279
    */
2284
2280
    if (dcarry)
2285
2281
      *--start1=dcarry;
2315
2311
        error=E_DEC_OVERFLOW;
2316
2312
        goto done;
2317
2313
      }
2318
 
      assert(intg0 <= ROUND_UP(from2->intg));
 
2314
      DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
2319
2315
      stop1=start1+frac0+intg0;
2320
 
      to->intg=cmin(intg0*DIG_PER_DEC1, from2->intg);
 
2316
      to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
2321
2317
    }
2322
2318
    if (unlikely(intg0+frac0 > to->len))
2323
2319
    {
2326
2322
      to->frac=frac0*DIG_PER_DEC1;
2327
2323
        error=E_DEC_TRUNCATED;
2328
2324
    }
2329
 
    assert(buf0 + (stop1 - start1) <= to->buf + to->len);
 
2325
    DBUG_ASSERT(buf0 + (stop1 - start1) <= to->buf + to->len);
2330
2326
    while (start1 < stop1)
2331
2327
        *buf0++=*start1++;
2332
2328
  }
2333
2329
done:
 
2330
  my_afree(tmp1);
2334
2331
  return error;
2335
2332
}
2336
2333
 
2507
2504
  {
2508
2505
    printf("0x");
2509
2506
    for (i=0; i < size; i++)
2510
 
      printf("%02x", ((unsigned char *)buf)[i]);
 
2507
      printf("%02x", ((uchar *)buf)[i]);
2511
2508
  }
2512
2509
  res=bin2decimal(buf, &a, p, s);
2513
2510
  printf(" => res=%d ", res);
2525
2522
  printf("\n");
2526
2523
}
2527
2524
 
2528
 
void test_ull2d(uint64_t from, const char *orig, int ex)
 
2525
void test_ull2d(ulonglong from, const char *orig, int ex)
2529
2526
{
2530
2527
  char s[100];
2531
2528
  int res;
2532
2529
 
2533
 
  res=uint64_t2decimal(from, &a);
2534
 
  int64_t10_to_str(from,s,10);
 
2530
  res=ulonglong2decimal(from, &a);
 
2531
  longlong10_to_str(from,s,10);
2535
2532
  printf("%-40s => res=%d    ", s, res);
2536
2533
  print_decimal(&a, orig, res, ex);
2537
2534
  printf("\n");
2538
2535
}
2539
2536
 
2540
 
void test_ll2d(int64_t from, const char *orig, int ex)
 
2537
void test_ll2d(longlong from, const char *orig, int ex)
2541
2538
{
2542
2539
  char s[100];
2543
2540
  int res;
2544
2541
 
2545
 
  res=int64_t2decimal(from, &a);
2546
 
  int64_t10_to_str(from,s,-10);
 
2542
  res=longlong2decimal(from, &a);
 
2543
  longlong10_to_str(from,s,-10);
2547
2544
  printf("%-40s => res=%d    ", s, res);
2548
2545
  print_decimal(&a, orig, res, ex);
2549
2546
  printf("\n");
2552
2549
void test_d2ull(const char *s, const char *orig, int ex)
2553
2550
{
2554
2551
  char s1[100], *end;
2555
 
  uint64_t x;
 
2552
  ulonglong x;
2556
2553
  int res;
2557
2554
 
2558
2555
  end= strend(s);
2559
2556
  string2decimal(s, &a, &end);
2560
 
  res=decimal2uint64_t(&a, &x);
 
2557
  res=decimal2ulonglong(&a, &x);
2561
2558
  if (full) dump_decimal(&a);
2562
 
  int64_t10_to_str(x,s1,10);
 
2559
  longlong10_to_str(x,s1,10);
2563
2560
  printf("%-40s => res=%d    %s\n", s, res, s1);
2564
2561
  check_result_code(res, ex);
2565
2562
  if (orig && strcmp(orig, s1))
2572
2569
void test_d2ll(const char *s, const char *orig, int ex)
2573
2570
{
2574
2571
  char s1[100], *end;
2575
 
  int64_t x;
 
2572
  longlong x;
2576
2573
  int res;
2577
2574
 
2578
2575
  end= strend(s);
2579
2576
  string2decimal(s, &a, &end);
2580
 
  res=decimal2int64_t(&a, &x);
 
2577
  res=decimal2longlong(&a, &x);
2581
2578
  if (full) dump_decimal(&a);
2582
 
  int64_t10_to_str(x,s1,-10);
 
2579
  longlong10_to_str(x,s1,-10);
2583
2580
  printf("%-40s => res=%d    %s\n", s, res, s1);
2584
2581
  check_result_code(res, ex);
2585
2582
  if (orig && strcmp(orig, s1))
2812
2809
  test_f2d(0.00012345000098765, 0);
2813
2810
  test_f2d(1234500009876.5, 0);
2814
2811
 
2815
 
  printf("==== uint64_t2decimal ====\n");
 
2812
  printf("==== ulonglong2decimal ====\n");
2816
2813
  test_ull2d(12345ULL, "12345", 0);
2817
2814
  test_ull2d(0ULL, "0", 0);
2818
2815
  test_ull2d(18446744073709551615ULL, "18446744073709551615", 0);
2819
2816
 
2820
 
  printf("==== decimal2uint64_t ====\n");
 
2817
  printf("==== decimal2ulonglong ====\n");
2821
2818
  test_d2ull("12345", "12345", 0);
2822
2819
  test_d2ull("0", "0", 0);
2823
2820
  test_d2ull("18446744073709551615", "18446744073709551615", 0);
2826
2823
  test_d2ull("1.23", "1", 1);
2827
2824
  test_d2ull("9999999999999999999999999.000", "9999999999999999", 2);
2828
2825
 
2829
 
  printf("==== int64_t2decimal ====\n");
 
2826
  printf("==== longlong2decimal ====\n");
2830
2827
  test_ll2d(12345LL, "-12345", 0);
2831
2828
  test_ll2d(1LL, "-1", 0);
2832
2829
  test_ll2d(9223372036854775807LL, "-9223372036854775807", 0);
2833
2830
  test_ll2d(9223372036854775808ULL, "-9223372036854775808", 0);
2834
2831
 
2835
 
  printf("==== decimal2int64_t ====\n");
 
2832
  printf("==== decimal2longlong ====\n");
2836
2833
  test_d2ll("18446744073709551615", "18446744073", 2);
2837
2834
  test_d2ll("-1", "-1", 0);
2838
2835
  test_d2ll("-1.23", "-1", 1);