~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to strings/decimal.c

  • Committer: Brian Aker
  • Date: 2008-07-20 05:41:52 UTC
  • Revision ID: brian@tangent.org-20080720054152-5laf6plsb0o7h6ss
Documentation cleanup

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
 
 
116
 
using namespace std;
117
 
 
118
 
namespace drizzled
119
 
{
 
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>
120
108
 
121
109
/*
122
110
  Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
140
128
#define DIG_MASK     100000000
141
129
#define DIG_BASE     1000000000
142
130
#define DIG_MAX      (DIG_BASE-1)
 
131
#define DIG_BASE2    ((dec2)DIG_BASE * (dec2)DIG_BASE)
143
132
#define ROUND_UP(X)  (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
144
133
static const dec1 powers10[DIG_PER_DEC1+1]={
145
134
  1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
224
213
          (to)=a;                                                       \
225
214
        } while(0)
226
215
 
227
 
/**
228
 
  Swap the contents of two variables.
229
 
 */
230
 
#define swap_variables(TYPE, a, b) \
231
 
  do {                             \
232
 
    TYPE dummy;                    \
233
 
    dummy= a;                      \
234
 
    a= b;                          \
235
 
    b= dummy;                      \
236
 
  } while (0)
237
 
 
238
 
 
239
216
/*
240
217
  Get maximum value for given precision and scale
241
218
 
255
232
  to->sign= 0;
256
233
  if ((intpart= to->intg= (precision - frac)))
257
234
  {
258
 
    const int firstdigits= intpart % DIG_PER_DEC1;
 
235
    int firstdigits= intpart % DIG_PER_DEC1;
259
236
    if (firstdigits)
260
237
      *buf++= powers10[firstdigits] - 1; /* get 9 99 999 ... */
261
238
    for(intpart/= DIG_PER_DEC1; intpart; intpart--)
264
241
 
265
242
  if ((to->frac= frac))
266
243
  {
267
 
    const int lastdigits= frac % DIG_PER_DEC1;
 
244
    int lastdigits= frac % DIG_PER_DEC1;
268
245
    for(frac/= DIG_PER_DEC1; frac; frac--)
269
246
      *buf++= DIG_MAX;
270
247
    if (lastdigits)
273
250
}
274
251
 
275
252
 
276
 
static dec1 *remove_leading_zeroes(const decimal_t *from, int *intg_result)
 
253
static dec1 *remove_leading_zeroes(decimal_t *from, int *intg_result)
277
254
{
278
255
  int intg= from->intg, i;
279
256
  dec1 *buf0= from->buf;
349
326
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
350
327
*/
351
328
 
352
 
int decimal2string(const decimal_t *from, char *to, int *to_len,
 
329
int decimal2string(decimal_t *from, char *to, int *to_len,
353
330
                   int fixed_precision, int fixed_decimals,
354
331
                   char filler)
355
332
{
421
398
      for (i=min(frac, DIG_PER_DEC1); i; i--)
422
399
      {
423
400
        dec1 y=x/DIG_MASK;
424
 
        *s1++='0'+(unsigned char)y;
 
401
        *s1++='0'+(uchar)y;
425
402
        x-=y*DIG_MASK;
426
403
        x*=10;
427
404
      }
444
421
      for (i=min(intg, DIG_PER_DEC1); i; i--)
445
422
      {
446
423
        dec1 y=x/10;
447
 
        *--s='0'+(unsigned char)(x-y*10);
 
424
        *--s='0'+(uchar)(x-y*10);
448
425
        x=y;
449
426
      }
450
427
    }
761
738
  beg= ROUND_UP(beg + 1) - 1;
762
739
  end= ROUND_UP(end) - 1;
763
740
  assert(new_point >= 0);
764
 
 
 
741
  
765
742
  /* We don't want negative new_point below */
766
743
  if (new_point != 0)
767
744
    new_point= ROUND_UP(new_point) - 1;
807
784
*/
808
785
 
809
786
int
810
 
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)
811
788
{
812
 
  char *s= from, *s1;
813
 
  char *end_of_string = *end;
814
 
  char *endp;
 
789
  const char *s= from, *s1, *endp, *end_of_string= *end;
815
790
  int i, intg, frac, error, intg1, frac1;
816
791
  dec1 x,*buf;
817
792
  sanity(to);
818
793
 
819
794
  error= E_DEC_BAD_NUM;                         /* In case of bad number */
820
 
  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))
821
796
    s++;
822
797
  if (s == end_of_string)
823
798
    goto fatal_error;
828
803
    s++;
829
804
 
830
805
  s1=s;
831
 
  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))
832
807
    s++;
833
808
  intg= (int) (s-s1);
834
809
  if (s < end_of_string && *s=='.')
835
810
  {
836
811
    endp= s+1;
837
 
    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))
838
813
      endp++;
839
814
    frac= (int) (endp - s - 1);
840
815
  }
844
819
    endp= s;
845
820
  }
846
821
 
847
 
  *end= endp;
 
822
  *end= (char*) endp;
848
823
 
849
824
  if (frac+intg == 0)
850
825
    goto fatal_error;
922
897
  if (endp+1 < end_of_string && (*endp == 'e' || *endp == 'E'))
923
898
  {
924
899
    int str_error;
925
 
    const int64_t exponent= internal::my_strtoll10(endp+1, (char**) &end_of_string,
926
 
                                                   &str_error);
 
900
    int64_t exponent= my_strtoll10(endp+1, (char**) &end_of_string,
 
901
                                    &str_error);
927
902
 
928
903
    if (end_of_string != endp +1)               /* If at least one digit */
929
904
    {
967
942
    E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
968
943
*/
969
944
 
970
 
int decimal2double(const decimal_t *from, double *to)
 
945
int decimal2double(decimal_t *from, double *to)
971
946
{
972
947
  char strbuf[FLOATING_POINT_BUFFER], *end;
973
948
  int len= sizeof(strbuf);
975
950
 
976
951
  rc = decimal2string(from, strbuf, &len, 0, 0, 0);
977
952
  end= strbuf + len;
978
 
 
979
 
  *to= internal::my_strtod(strbuf, &end, &error);
980
 
 
 
953
  
 
954
  *to= my_strtod(strbuf, &end, &error);
 
955
             
981
956
  return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
982
957
}
983
958
 
993
968
    E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
994
969
*/
995
970
 
996
 
int double2decimal(const double from, decimal_t *to)
 
971
int double2decimal(double from, decimal_t *to)
997
972
{
998
973
  char buff[FLOATING_POINT_BUFFER], *end;
999
974
  int res;
1000
 
  end= buff + internal::my_gcvt(from,
1001
 
                                internal::MY_GCVT_ARG_DOUBLE,
1002
 
                                sizeof(buff) - 1, buff, NULL);
 
975
  end= buff + my_gcvt(from, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
1003
976
  res= string2decimal(buff, to, &end);
1004
977
  return(res);
1005
978
}
1031
1004
  return error;
1032
1005
}
1033
1006
 
1034
 
int uint64_t2decimal(const uint64_t from, decimal_t *to)
 
1007
int uint64_t2decimal(uint64_t from, decimal_t *to)
1035
1008
{
1036
1009
  to->sign=0;
1037
1010
  return ull2dec(from, to);
1038
1011
}
1039
1012
 
1040
 
int int64_t2decimal(const int64_t from, decimal_t *to)
 
1013
int int64_t2decimal(int64_t from, decimal_t *to)
1041
1014
{
1042
1015
  if ((to->sign= from < 0))
1043
1016
    return ull2dec(-from, to);
1044
1017
  return ull2dec(from, to);
1045
1018
}
1046
1019
 
1047
 
int decimal2uint64_t(const decimal_t *from, uint64_t *to)
 
1020
int decimal2uint64_t(decimal_t *from, uint64_t *to)
1048
1021
{
1049
1022
  dec1 *buf=from->buf;
1050
1023
  uint64_t x=0;
1073
1046
  return E_DEC_OK;
1074
1047
}
1075
1048
 
1076
 
int decimal2int64_t(const decimal_t *from, int64_t *to)
 
1049
int decimal2int64_t(decimal_t *from, int64_t *to)
1077
1050
{
1078
1051
  dec1 *buf=from->buf;
1079
1052
  int64_t x=0;
1192
1165
 
1193
1166
                7E F2 04 37 2D FB 2D
1194
1167
*/
1195
 
int decimal2bin(const decimal_t *from, unsigned char *to, int precision, int frac)
 
1168
int decimal2bin(decimal_t *from, uchar *to, int precision, int frac)
1196
1169
{
1197
1170
  dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
1198
1171
  int error=E_DEC_OK, intg=precision-frac,
1208
1181
      fsize1=frac1*sizeof(dec1)+dig2bytes[frac1x];
1209
1182
  const int orig_isize0= isize0;
1210
1183
  const int orig_fsize0= fsize0;
1211
 
  unsigned char *orig_to= to;
 
1184
  uchar *orig_to= to;
1212
1185
 
1213
1186
  buf1= remove_leading_zeroes(from, &from_intg);
1214
1187
 
1298
1271
  }
1299
1272
  if (fsize0 > fsize1)
1300
1273
  {
1301
 
    unsigned char *to_end= orig_to + orig_fsize0 + orig_isize0;
 
1274
    uchar *to_end= orig_to + orig_fsize0 + orig_isize0;
1302
1275
 
1303
1276
    while (fsize0-- > fsize1 && to < to_end)
1304
 
      *to++= (unsigned char)mask;
 
1277
      *to++= (uchar)mask;
1305
1278
  }
1306
1279
  orig_to[0]^= 0x80;
1307
1280
 
1327
1300
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1328
1301
*/
1329
1302
 
1330
 
int bin2decimal(const unsigned char *from, decimal_t *to, int precision, int scale)
 
1303
int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale)
1331
1304
{
1332
1305
  int error=E_DEC_OK, intg=precision-scale,
1333
1306
      intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1334
1307
      intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1,
1335
1308
      intg1=intg0+(intg0x>0), frac1=frac0+(frac0x>0);
1336
1309
  dec1 *buf=to->buf, mask=(*from & 0x80) ? 0 : -1;
1337
 
  const unsigned char *stop;
1338
 
  unsigned char *d_copy;
 
1310
  const uchar *stop;
 
1311
  uchar *d_copy;
1339
1312
  int bin_size= decimal_bin_size(precision, scale);
1340
1313
 
1341
1314
  sanity(to);
1342
 
  d_copy= (unsigned char*) alloca(bin_size);
 
1315
  d_copy= (uchar*) my_alloca(bin_size);
1343
1316
  memcpy(d_copy, from, bin_size);
1344
1317
  d_copy[0]^= 0x80;
1345
1318
  from= d_copy;
1389
1362
  {
1390
1363
    assert(sizeof(dec1) == 4);
1391
1364
    *buf=mi_sint4korr(from) ^ mask;
1392
 
    if (((uint32_t)*buf) > DIG_MAX)
 
1365
    if (((uint32)*buf) > DIG_MAX)
1393
1366
      goto err;
1394
1367
    if (buf > to->buf || *buf != 0)
1395
1368
      buf++;
1401
1374
  {
1402
1375
    assert(sizeof(dec1) == 4);
1403
1376
    *buf=mi_sint4korr(from) ^ mask;
1404
 
    if (((uint32_t)*buf) > DIG_MAX)
 
1377
    if (((uint32)*buf) > DIG_MAX)
1405
1378
      goto err;
1406
1379
    buf++;
1407
1380
  }
1418
1391
      default: assert(0);
1419
1392
    }
1420
1393
    *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
1421
 
    if (((uint32_t)*buf) > DIG_MAX)
 
1394
    if (((uint32)*buf) > DIG_MAX)
1422
1395
      goto err;
1423
1396
    buf++;
1424
1397
  }
 
1398
  my_afree(d_copy);
1425
1399
  return error;
1426
1400
 
1427
1401
err:
 
1402
  my_afree(d_copy);
1428
1403
  decimal_make_zero(((decimal_t*) to));
1429
1404
  return(E_DEC_BAD_NUM);
1430
1405
}
1431
1406
 
1432
1407
/*
 
1408
  Returns the size of array to hold a decimal with given precision and scale
 
1409
 
 
1410
  RETURN VALUE
 
1411
    size in dec1
 
1412
    (multiply by sizeof(dec1) to get the size if bytes)
 
1413
*/
 
1414
 
 
1415
int decimal_size(int precision, int scale)
 
1416
{
 
1417
  assert(scale >= 0 && precision > 0 && scale <= precision);
 
1418
  return ROUND_UP(precision-scale)+ROUND_UP(scale);
 
1419
}
 
1420
 
 
1421
/*
1433
1422
  Returns the size of array to hold a binary representation of a decimal
1434
1423
 
1435
1424
  RETURN VALUE
1466
1455
*/
1467
1456
 
1468
1457
int
1469
 
decimal_round(const decimal_t *from, decimal_t *to, int scale,
 
1458
decimal_round(decimal_t *from, decimal_t *to, int scale,
1470
1459
              decimal_round_mode mode)
1471
1460
{
1472
1461
  int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
1658
1647
  return error;
1659
1648
}
1660
1649
 
1661
 
static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
1650
/*
 
1651
  Returns the size of the result of the operation
 
1652
 
 
1653
  SYNOPSIS
 
1654
    decimal_result_size()
 
1655
      from1   - operand of the unary operation or first operand of the
 
1656
                binary operation
 
1657
      from2   - second operand of the binary operation
 
1658
      op      - operation. one char '+', '-', '*', '/' are allowed
 
1659
                others may be added later
 
1660
      param   - extra param to the operation. unused for '+', '-', '*'
 
1661
                scale increment for '/'
 
1662
 
 
1663
  NOTE
 
1664
    returned valued may be larger than the actual buffer requred
 
1665
    in the operation, as decimal_result_size, by design, operates on
 
1666
    precision/scale values only and not on the actual decimal number
 
1667
 
 
1668
  RETURN VALUE
 
1669
    size of to->buf array in dec1 elements. to get size in bytes
 
1670
    multiply by sizeof(dec1)
 
1671
*/
 
1672
 
 
1673
int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, int param)
 
1674
{
 
1675
  switch (op) {
 
1676
  case '-':
 
1677
    return ROUND_UP(max(from1->intg, from2->intg)) +
 
1678
           ROUND_UP(max(from1->frac, from2->frac));
 
1679
  case '+':
 
1680
    return ROUND_UP(max(from1->intg, from2->intg)+1) +
 
1681
           ROUND_UP(max(from1->frac, from2->frac));
 
1682
  case '*':
 
1683
    return ROUND_UP(from1->intg+from2->intg)+
 
1684
           ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
 
1685
  case '/':
 
1686
    return ROUND_UP(from1->intg+from2->intg+1+from1->frac+from2->frac+param);
 
1687
  default: assert(0);
 
1688
  }
 
1689
  return -1; /* shut up the warning */
 
1690
}
 
1691
 
 
1692
static int do_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
1662
1693
{
1663
1694
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1664
1695
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1698
1729
    set_if_smaller(intg2, intg0);
1699
1730
  }
1700
1731
 
1701
 
  /* part 1 - cmax(frac) ... cmin(frac) */
 
1732
  /* part 1 - max(frac) ... min (frac) */
1702
1733
  if (frac1 > frac2)
1703
1734
  {
1704
1735
    buf1=from1->buf+intg1+frac1;
1716
1747
  while (buf1 > stop)
1717
1748
    *--buf0=*--buf1;
1718
1749
 
1719
 
  /* part 2 - cmin(frac) ... cmin(intg) */
 
1750
  /* part 2 - min(frac) ... min(intg) */
1720
1751
  carry=0;
1721
1752
  while (buf1 > stop2)
1722
1753
  {
1723
1754
    ADD(*--buf0, *--buf1, *--buf2, carry);
1724
1755
  }
1725
1756
 
1726
 
  /* part 3 - cmin(intg) ... cmax(intg) */
 
1757
  /* part 3 - min(intg) ... max(intg) */
1727
1758
  buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
1728
1759
                        ((stop=from2->buf)+intg2-intg1) ;
1729
1760
  while (buf1 > stop)
1740
1771
 
1741
1772
/* to=from1-from2.
1742
1773
   if to==0, return -1/0/+1 - the result of the comparison */
1743
 
static int do_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
1774
static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
1744
1775
{
1745
1776
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1746
1777
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
1809
1840
  /* ensure that always from1 > from2 (and intg1 >= intg2) */
1810
1841
  if (carry)
1811
1842
  {
1812
 
    swap_variables(const decimal_t *,from1, from2);
 
1843
    swap_variables(decimal_t *,from1,from1);
1813
1844
    swap_variables(dec1 *,start1, start2);
1814
1845
    swap_variables(int,intg1,intg2);
1815
1846
    swap_variables(int,frac1,frac2);
1830
1861
  }
1831
1862
  carry=0;
1832
1863
 
1833
 
  /* part 1 - cmax(frac) ... cmin(frac) */
 
1864
  /* part 1 - max(frac) ... min (frac) */
1834
1865
  if (frac1 > frac2)
1835
1866
  {
1836
1867
    buf1=start1+intg1+frac1;
1854
1885
    }
1855
1886
  }
1856
1887
 
1857
 
  /* part 2 - cmin(frac) ... intg2 */
 
1888
  /* part 2 - min(frac) ... intg2 */
1858
1889
  while (buf2 > start2)
1859
1890
  {
1860
1891
    SUB(*--buf0, *--buf1, *--buf2, carry);
1875
1906
  return error;
1876
1907
}
1877
1908
 
1878
 
int decimal_intg(const decimal_t *from)
 
1909
int decimal_intg(decimal_t *from)
1879
1910
{
1880
1911
  int res;
1881
1912
  dec1 *tmp_res;
1883
1914
  return res;
1884
1915
}
1885
1916
 
1886
 
int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
1917
int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
1887
1918
{
1888
1919
  if (likely(from1->sign == from2->sign))
1889
1920
    return do_add(from1, from2, to);
1890
1921
  return do_sub(from1, from2, to);
1891
1922
}
1892
1923
 
1893
 
int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
1924
int decimal_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
1894
1925
{
1895
1926
  if (likely(from1->sign == from2->sign))
1896
1927
    return do_sub(from1, from2, to);
1897
1928
  return do_add(from1, from2, to);
1898
1929
}
1899
1930
 
1900
 
int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
 
1931
int decimal_cmp(decimal_t *from1, decimal_t *from2)
1901
1932
{
1902
1933
  if (likely(from1->sign == from2->sign))
1903
1934
    return do_sub(from1, from2, 0);
1904
1935
  return from1->sign > from2->sign ? -1 : 1;
1905
1936
}
1906
1937
 
1907
 
int decimal_is_zero(const decimal_t *from)
 
1938
int decimal_is_zero(decimal_t *from)
1908
1939
{
1909
1940
  dec1 *buf1=from->buf,
1910
1941
       *end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
1935
1966
    XXX if this library is to be used with huge numbers of thousands of
1936
1967
    digits, fast multiplication must be implemented.
1937
1968
*/
1938
 
int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
1969
int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to)
1939
1970
{
1940
1971
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1941
1972
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1978
2009
  stop1=buf1-intg1;
1979
2010
  stop2=buf2-intg2;
1980
2011
 
1981
 
  memset(to->buf, 0, (intg0+frac0)*sizeof(dec1));
 
2012
  bzero(to->buf, (intg0+frac0)*sizeof(dec1));
1982
2013
 
1983
2014
  for (buf1+=frac1-1; buf1 >= stop1; buf1--, start0--)
1984
2015
  {
2051
2082
  changed to malloc (or at least fallback to malloc if alloca() fails)
2052
2083
  but then, decimal_mul() should be rewritten too :(
2053
2084
*/
2054
 
static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
 
2085
static int do_div_mod(decimal_t *from1, decimal_t *from2,
2055
2086
                       decimal_t *to, decimal_t *mod, int scale_incr)
2056
2087
{
2057
2088
  int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2110
2141
  {
2111
2142
    /* we're calculating N1 % N2.
2112
2143
       The result will have
2113
 
         frac=cmax(frac1, frac2), as for subtraction
 
2144
         frac=max(frac1, frac2), as for subtraction
2114
2145
         intg=intg2
2115
2146
    */
2116
2147
    to->sign=from1->sign;
2143
2174
 
2144
2175
  len1=(i=ROUND_UP(prec1))+ROUND_UP(2*frac2+scale_incr+1) + 1;
2145
2176
  set_if_bigger(len1, 3);
2146
 
  if (!(tmp1=(dec1 *)alloca(len1*sizeof(dec1))))
 
2177
  if (!(tmp1=(dec1 *)my_alloca(len1*sizeof(dec1))))
2147
2178
    return E_DEC_OOM;
2148
2179
  memcpy(tmp1, buf1, i*sizeof(dec1));
2149
 
  memset(tmp1+i, 0, (len1-i)*sizeof(dec1));
 
2180
  bzero(tmp1+i, (len1-i)*sizeof(dec1));
2150
2181
 
2151
2182
  start1=tmp1;
2152
2183
  stop1=start1+len1;
2238
2269
    /*
2239
2270
      now the result is in tmp1, it has
2240
2271
        intg=prec1-frac1
2241
 
        frac=cmax(frac1, frac2)=to->frac
 
2272
        frac=max(frac1, frac2)=to->frac
2242
2273
    */
2243
2274
    if (dcarry)
2244
2275
      *--start1=dcarry;
2290
2321
        *buf0++=*start1++;
2291
2322
  }
2292
2323
done:
 
2324
  my_afree(tmp1);
2293
2325
  return error;
2294
2326
}
2295
2327
 
2310
2342
*/
2311
2343
 
2312
2344
int
2313
 
decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, int scale_incr)
 
2345
decimal_div(decimal_t *from1, decimal_t *from2, decimal_t *to, int scale_incr)
2314
2346
{
2315
2347
  return do_div_mod(from1, from2, to, 0, scale_incr);
2316
2348
}
2342
2374
   thus, there's no requirement for M or N to be integers
2343
2375
*/
2344
2376
 
2345
 
int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
2377
int decimal_mod(decimal_t *from1, decimal_t *from2, decimal_t *to)
2346
2378
{
2347
2379
  return do_div_mod(from1, from2, 0, to, 0);
2348
2380
}
2349
2381
 
2350
 
} /* namespace drizzled */
2351
 
 
2352
2382
#ifdef MAIN
2353
2383
 
2354
2384
int full= 0;
2468
2498
  {
2469
2499
    printf("0x");
2470
2500
    for (i=0; i < size; i++)
2471
 
      printf("%02x", ((unsigned char *)buf)[i]);
 
2501
      printf("%02x", ((uchar *)buf)[i]);
2472
2502
  }
2473
2503
  res=bin2decimal(buf, &a, p, s);
2474
2504
  printf(" => res=%d ", res);
2492
2522
  int res;
2493
2523
 
2494
2524
  res=uint64_t2decimal(from, &a);
2495
 
  internal::int64_t10_to_str(from,s,10);
 
2525
  int64_t10_to_str(from,s,10);
2496
2526
  printf("%-40s => res=%d    ", s, res);
2497
2527
  print_decimal(&a, orig, res, ex);
2498
2528
  printf("\n");
2504
2534
  int res;
2505
2535
 
2506
2536
  res=int64_t2decimal(from, &a);
2507
 
  internal::int64_t10_to_str(from,s,-10);
 
2537
  int64_t10_to_str(from,s,-10);
2508
2538
  printf("%-40s => res=%d    ", s, res);
2509
2539
  print_decimal(&a, orig, res, ex);
2510
2540
  printf("\n");
2520
2550
  string2decimal(s, &a, &end);
2521
2551
  res=decimal2uint64_t(&a, &x);
2522
2552
  if (full) dump_decimal(&a);
2523
 
  internal::int64_t10_to_str(x,s1,10);
 
2553
  int64_t10_to_str(x,s1,10);
2524
2554
  printf("%-40s => res=%d    %s\n", s, res, s1);
2525
2555
  check_result_code(res, ex);
2526
2556
  if (orig && strcmp(orig, s1))
2540
2570
  string2decimal(s, &a, &end);
2541
2571
  res=decimal2int64_t(&a, &x);
2542
2572
  if (full) dump_decimal(&a);
2543
 
  internal::int64_t10_to_str(x,s1,-10);
 
2573
  int64_t10_to_str(x,s1,-10);
2544
2574
  printf("%-40s => res=%d    %s\n", s, res, s1);
2545
2575
  check_result_code(res, ex);
2546
2576
  if (orig && strcmp(orig, s1))