~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/decimal.cc

  • Committer: Eric Day
  • Date: 2010-01-07 20:02:38 UTC
  • mfrom: (1259.4.2 staging)
  • mto: This revision was merged to the branch mainline in revision 1271.
  • Revision ID: eday@oddments.org-20100107200238-uqw8v6kv9pl7nny5
Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
97
97
      implementation-defined.
98
98
*/
99
99
 
100
 
#include <drizzled/global.h>
 
100
#include "config.h"
101
101
 
102
 
#include "m_string.h"
103
 
#include "m_ctype.h"
104
 
#include "decimal.h"
 
102
#include "drizzled/definitions.h"
 
103
#include "drizzled/internal/m_string.h"
 
104
#include "drizzled/charset_info.h"
 
105
#include "drizzled/decimal.h"
105
106
 
106
107
#include <plugin/myisam/myisampack.h>
107
108
#include <drizzled/util/test.h>
270
271
}
271
272
 
272
273
 
273
 
static dec1 *remove_leading_zeroes(decimal_t *from, int *intg_result)
 
274
static dec1 *remove_leading_zeroes(const decimal_t *from, int *intg_result)
274
275
{
275
276
  int intg= from->intg, i;
276
277
  dec1 *buf0= from->buf;
346
347
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
347
348
*/
348
349
 
349
 
int decimal2string(decimal_t *from, char *to, int *to_len,
 
350
int decimal2string(const decimal_t *from, char *to, int *to_len,
350
351
                   int fixed_precision, int fixed_decimals,
351
352
                   char filler)
352
353
{
964
965
    E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
965
966
*/
966
967
 
967
 
int decimal2double(decimal_t *from, double *to)
 
968
int decimal2double(const decimal_t *from, double *to)
968
969
{
969
970
  char strbuf[FLOATING_POINT_BUFFER], *end;
970
971
  int len= sizeof(strbuf);
990
991
    E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
991
992
*/
992
993
 
993
 
int double2decimal(double from, decimal_t *to)
 
994
int double2decimal(const double from, decimal_t *to)
994
995
{
995
996
  char buff[FLOATING_POINT_BUFFER], *end;
996
997
  int res;
1026
1027
  return error;
1027
1028
}
1028
1029
 
1029
 
int uint64_t2decimal(uint64_t from, decimal_t *to)
 
1030
int uint64_t2decimal(const uint64_t from, decimal_t *to)
1030
1031
{
1031
1032
  to->sign=0;
1032
1033
  return ull2dec(from, to);
1033
1034
}
1034
1035
 
1035
 
int int64_t2decimal(int64_t from, decimal_t *to)
 
1036
int int64_t2decimal(const int64_t from, decimal_t *to)
1036
1037
{
1037
1038
  if ((to->sign= from < 0))
1038
1039
    return ull2dec(-from, to);
1039
1040
  return ull2dec(from, to);
1040
1041
}
1041
1042
 
1042
 
int decimal2uint64_t(decimal_t *from, uint64_t *to)
 
1043
int decimal2uint64_t(const decimal_t *from, uint64_t *to)
1043
1044
{
1044
1045
  dec1 *buf=from->buf;
1045
1046
  uint64_t x=0;
1068
1069
  return E_DEC_OK;
1069
1070
}
1070
1071
 
1071
 
int decimal2int64_t(decimal_t *from, int64_t *to)
 
1072
int decimal2int64_t(const decimal_t *from, int64_t *to)
1072
1073
{
1073
1074
  dec1 *buf=from->buf;
1074
1075
  int64_t x=0;
1187
1188
 
1188
1189
                7E F2 04 37 2D FB 2D
1189
1190
*/
1190
 
int decimal2bin(decimal_t *from, unsigned char *to, int precision, int frac)
 
1191
int decimal2bin(const decimal_t *from, unsigned char *to, int precision, int frac)
1191
1192
{
1192
1193
  dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
1193
1194
  int error=E_DEC_OK, intg=precision-frac,
1461
1462
*/
1462
1463
 
1463
1464
int
1464
 
decimal_round(decimal_t *from, decimal_t *to, int scale,
 
1465
decimal_round(const decimal_t *from, decimal_t *to, int scale,
1465
1466
              decimal_round_mode mode)
1466
1467
{
1467
1468
  int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
1653
1654
  return error;
1654
1655
}
1655
1656
 
1656
 
static int do_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
 
1657
static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1657
1658
{
1658
1659
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1659
1660
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1735
1736
 
1736
1737
/* to=from1-from2.
1737
1738
   if to==0, return -1/0/+1 - the result of the comparison */
1738
 
static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
 
1739
static int do_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1739
1740
{
1740
1741
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1741
1742
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
1804
1805
  /* ensure that always from1 > from2 (and intg1 >= intg2) */
1805
1806
  if (carry)
1806
1807
  {
1807
 
    swap_variables(decimal_t *,from1,from1);
 
1808
    swap_variables(const decimal_t *,from1, from2);
1808
1809
    swap_variables(dec1 *,start1, start2);
1809
1810
    swap_variables(int,intg1,intg2);
1810
1811
    swap_variables(int,frac1,frac2);
1870
1871
  return error;
1871
1872
}
1872
1873
 
1873
 
int decimal_intg(decimal_t *from)
 
1874
int decimal_intg(const decimal_t *from)
1874
1875
{
1875
1876
  int res;
1876
1877
  dec1 *tmp_res;
1878
1879
  return res;
1879
1880
}
1880
1881
 
1881
 
int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
 
1882
int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1882
1883
{
1883
1884
  if (likely(from1->sign == from2->sign))
1884
1885
    return do_add(from1, from2, to);
1885
1886
  return do_sub(from1, from2, to);
1886
1887
}
1887
1888
 
1888
 
int decimal_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
 
1889
int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1889
1890
{
1890
1891
  if (likely(from1->sign == from2->sign))
1891
1892
    return do_sub(from1, from2, to);
1892
1893
  return do_add(from1, from2, to);
1893
1894
}
1894
1895
 
1895
 
int decimal_cmp(decimal_t *from1, decimal_t *from2)
 
1896
int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
1896
1897
{
1897
1898
  if (likely(from1->sign == from2->sign))
1898
1899
    return do_sub(from1, from2, 0);
1899
1900
  return from1->sign > from2->sign ? -1 : 1;
1900
1901
}
1901
1902
 
1902
 
int decimal_is_zero(decimal_t *from)
 
1903
int decimal_is_zero(const decimal_t *from)
1903
1904
{
1904
1905
  dec1 *buf1=from->buf,
1905
1906
       *end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
1930
1931
    XXX if this library is to be used with huge numbers of thousands of
1931
1932
    digits, fast multiplication must be implemented.
1932
1933
*/
1933
 
int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to)
 
1934
int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1934
1935
{
1935
1936
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1936
1937
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
2046
2047
  changed to malloc (or at least fallback to malloc if alloca() fails)
2047
2048
  but then, decimal_mul() should be rewritten too :(
2048
2049
*/
2049
 
static int do_div_mod(decimal_t *from1, decimal_t *from2,
 
2050
static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
2050
2051
                       decimal_t *to, decimal_t *mod, int scale_incr)
2051
2052
{
2052
2053
  int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2305
2306
*/
2306
2307
 
2307
2308
int
2308
 
decimal_div(decimal_t *from1, decimal_t *from2, decimal_t *to, int scale_incr)
 
2309
decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, int scale_incr)
2309
2310
{
2310
2311
  return do_div_mod(from1, from2, to, 0, scale_incr);
2311
2312
}
2337
2338
   thus, there's no requirement for M or N to be integers
2338
2339
*/
2339
2340
 
2340
 
int decimal_mod(decimal_t *from1, decimal_t *from2, decimal_t *to)
 
2341
int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2341
2342
{
2342
2343
  return do_div_mod(from1, from2, 0, to, 0);
2343
2344
}