97
97
implementation-defined.
100
#include <drizzled/global.h>
102
#include "m_string.h"
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>
107
108
#include <drizzled/util/test.h>
346
347
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
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,
964
965
E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
967
int decimal2double(decimal_t *from, double *to)
968
int decimal2double(const decimal_t *from, double *to)
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
993
int double2decimal(double from, decimal_t *to)
994
int double2decimal(const double from, decimal_t *to)
995
996
char buff[FLOATING_POINT_BUFFER], *end;
1029
int uint64_t2decimal(uint64_t from, decimal_t *to)
1030
int uint64_t2decimal(const uint64_t from, decimal_t *to)
1032
1033
return ull2dec(from, to);
1035
int int64_t2decimal(int64_t from, decimal_t *to)
1036
int int64_t2decimal(const int64_t from, decimal_t *to)
1037
1038
if ((to->sign= from < 0))
1038
1039
return ull2dec(-from, to);
1039
1040
return ull2dec(from, to);
1042
int decimal2uint64_t(decimal_t *from, uint64_t *to)
1043
int decimal2uint64_t(const decimal_t *from, uint64_t *to)
1044
1045
dec1 *buf=from->buf;
1188
1189
7E F2 04 37 2D FB 2D
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)
1192
1193
dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
1193
1194
int error=E_DEC_OK, intg=precision-frac,
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)
1467
1468
int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
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)
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),
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)
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) */
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);
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)
1883
1884
if (likely(from1->sign == from2->sign))
1884
1885
return do_add(from1, from2, to);
1885
1886
return do_sub(from1, from2, to);
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)
1890
1891
if (likely(from1->sign == from2->sign))
1891
1892
return do_sub(from1, from2, to);
1892
1893
return do_add(from1, from2, to);
1895
int decimal_cmp(decimal_t *from1, decimal_t *from2)
1896
int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
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;
1902
int decimal_is_zero(decimal_t *from)
1903
int decimal_is_zero(const decimal_t *from)
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.
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)
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 :(
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)
2052
2053
int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
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)
2310
2311
return do_div_mod(from1, from2, to, 0, scale_incr);
2337
2338
thus, there's no requirement for M or N to be integers
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)
2342
2343
return do_div_mod(from1, from2, 0, to, 0);