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 */
17
19
=======================================================================
18
20
NOTE: this library implements SQL standard "exact numeric" type
97
99
implementation-defined.
102
#include "drizzled/definitions.h"
103
#include "drizzled/internal/m_string.h"
104
#include "drizzled/charset_info.h"
105
#include "drizzled/decimal.h"
107
#include <plugin/myisam/myisampack.h>
108
#include <drizzled/util/test.h>
102
#include <my_global.h>
104
#include <myisampack.h>
105
#include <my_sys.h> /* for my_alloca */
106
#include <m_string.h>
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};
256
233
if ((intpart= to->intg= (precision - frac)))
258
const int firstdigits= intpart % DIG_PER_DEC1;
235
int firstdigits= intpart % DIG_PER_DEC1;
260
237
*buf++= powers10[firstdigits] - 1; /* get 9 99 999 ... */
261
238
for(intpart/= DIG_PER_DEC1; intpart; intpart--)
349
326
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
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,
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)
813
char *end_of_string = *end;
789
const char *s= from, *s1, *endp, *end_of_string= *end;
815
790
int i, intg, frac, error, intg1, frac1;
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))
822
797
if (s == end_of_string)
823
798
goto fatal_error;
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))
833
808
intg= (int) (s-s1);
834
809
if (s < end_of_string && *s=='.')
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))
839
814
frac= (int) (endp - s - 1);
922
897
if (endp+1 < end_of_string && (*endp == 'e' || *endp == 'E'))
925
const int64_t exponent= internal::my_strtoll10(endp+1, (char**) &end_of_string,
900
int64_t exponent= my_strtoll10(endp+1, (char**) &end_of_string,
928
903
if (end_of_string != endp +1) /* If at least one digit */
967
942
E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
970
int decimal2double(const decimal_t *from, double *to)
945
int decimal2double(decimal_t *from, double *to)
972
947
char strbuf[FLOATING_POINT_BUFFER], *end;
973
948
int len= sizeof(strbuf);
976
951
rc = decimal2string(from, strbuf, &len, 0, 0, 0);
977
952
end= strbuf + len;
979
*to= internal::my_strtod(strbuf, &end, &error);
954
*to= my_strtod(strbuf, &end, &error);
981
956
return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
993
968
E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
996
int double2decimal(const double from, decimal_t *to)
971
int double2decimal(double from, decimal_t *to)
998
973
char buff[FLOATING_POINT_BUFFER], *end;
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);
1034
int uint64_t2decimal(const uint64_t from, decimal_t *to)
1007
int uint64_t2decimal(uint64_t from, decimal_t *to)
1037
1010
return ull2dec(from, to);
1040
int int64_t2decimal(const int64_t from, decimal_t *to)
1013
int int64_t2decimal(int64_t from, decimal_t *to)
1042
1015
if ((to->sign= from < 0))
1043
1016
return ull2dec(-from, to);
1044
1017
return ull2dec(from, to);
1047
int decimal2uint64_t(const decimal_t *from, uint64_t *to)
1020
int decimal2uint64_t(decimal_t *from, uint64_t *to)
1049
1022
dec1 *buf=from->buf;
1193
1166
7E F2 04 37 2D FB 2D
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)
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;
1213
1186
buf1= remove_leading_zeroes(from, &from_intg);
1327
1300
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
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)
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;
1339
1312
int bin_size= decimal_bin_size(precision, scale);
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;
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)
1394
1367
if (buf > to->buf || *buf != 0)
1418
1391
default: assert(0);
1420
1393
*buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
1421
if (((uint32_t)*buf) > DIG_MAX)
1394
if (((uint32)*buf) > DIG_MAX)
1428
1403
decimal_make_zero(((decimal_t*) to));
1429
1404
return(E_DEC_BAD_NUM);
1408
Returns the size of array to hold a decimal with given precision and scale
1412
(multiply by sizeof(dec1) to get the size if bytes)
1415
int decimal_size(int precision, int scale)
1417
assert(scale >= 0 && precision > 0 && scale <= precision);
1418
return ROUND_UP(precision-scale)+ROUND_UP(scale);
1433
1422
Returns the size of array to hold a binary representation of a decimal
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)
1472
1461
int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
1661
static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1651
Returns the size of the result of the operation
1654
decimal_result_size()
1655
from1 - operand of the unary operation or first operand of the
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 '/'
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
1669
size of to->buf array in dec1 elements. to get size in bytes
1670
multiply by sizeof(dec1)
1673
int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, int param)
1677
return ROUND_UP(max(from1->intg, from2->intg)) +
1678
ROUND_UP(max(from1->frac, from2->frac));
1680
return ROUND_UP(max(from1->intg, from2->intg)+1) +
1681
ROUND_UP(max(from1->frac, from2->frac));
1683
return ROUND_UP(from1->intg+from2->intg)+
1684
ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
1686
return ROUND_UP(from1->intg+from2->intg+1+from1->frac+from2->frac+param);
1689
return -1; /* shut up the warning */
1692
static int do_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
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);
1701
/* part 1 - cmax(frac) ... cmin(frac) */
1732
/* part 1 - max(frac) ... min (frac) */
1702
1733
if (frac1 > frac2)
1704
1735
buf1=from1->buf+intg1+frac1;
1716
1747
while (buf1 > stop)
1717
1748
*--buf0=*--buf1;
1719
/* part 2 - cmin(frac) ... cmin(intg) */
1750
/* part 2 - min(frac) ... min(intg) */
1721
1752
while (buf1 > stop2)
1723
1754
ADD(*--buf0, *--buf1, *--buf2, carry);
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)
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)
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) */
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);
1857
/* part 2 - cmin(frac) ... intg2 */
1888
/* part 2 - min(frac) ... intg2 */
1858
1889
while (buf2 > start2)
1860
1891
SUB(*--buf0, *--buf1, *--buf2, carry);
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)
1888
1919
if (likely(from1->sign == from2->sign))
1889
1920
return do_add(from1, from2, to);
1890
1921
return do_sub(from1, from2, to);
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)
1895
1926
if (likely(from1->sign == from2->sign))
1896
1927
return do_sub(from1, from2, to);
1897
1928
return do_add(from1, from2, to);
1900
int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
1931
int decimal_cmp(decimal_t *from1, decimal_t *from2)
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;
1907
int decimal_is_zero(const decimal_t *from)
1938
int decimal_is_zero(decimal_t *from)
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.
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)
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;
1981
memset(to->buf, 0, (intg0+frac0)*sizeof(dec1));
2012
bzero(to->buf, (intg0+frac0)*sizeof(dec1));
1983
2014
for (buf1+=frac1-1; buf1 >= stop1; buf1--, start0--)
2051
2082
changed to malloc (or at least fallback to malloc if alloca() fails)
2052
2083
but then, decimal_mul() should be rewritten too :(
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)
2057
2088
int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
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
2116
2147
to->sign=from1->sign;
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));
2152
2183
stop1=start1+len1;
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)
2315
2347
return do_div_mod(from1, from2, to, 0, scale_incr);
2342
2374
thus, there's no requirement for M or N to be integers
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)
2347
2379
return do_div_mod(from1, from2, 0, to, 0);
2350
} /* namespace drizzled */
2470
2500
for (i=0; i < size; i++)
2471
printf("%02x", ((unsigned char *)buf)[i]);
2501
printf("%02x", ((uchar *)buf)[i]);
2473
2503
res=bin2decimal(buf, &a, p, s);
2474
2504
printf(" => res=%d ", res);
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);
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);
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))